6/9, LinkedList,链表基础,反转与删除
这种 swap 中有个很有意思的性质,如果下一行的等号左面等于上一行的等号右边,并且以第一行的等号左边结尾,那最后实际做的事情是 swap 了第一行等号右,和最后一行等号左。
Copy public class Solution {
public ListNode reverseList ( ListNode head) {
ListNode prev = null ;
while (head != null ){
ListNode temp = head . next ;
head . next = prev;
prev = head;
head = temp;
}
return prev;
}
}
Copy public class Solution {
public ListNode reverseBetween ( ListNode head , int m , int n) {
if (m == n) return head;
ListNode dummy = new ListNode( 0 ) ;
dummy . next = head;
ListNode prev = dummy;
ListNode cur = head;
for ( int i = 0 ; i < m - 1 ; i ++ ){
prev = prev . next ;
cur = cur . next ;
}
for ( int i = 0 ; i < n - m; i ++ ){
ListNode next = cur . next ;
cur . next = next . next ;
next . next = prev . next ;
prev . next = next;
}
return dummy . next ;
}
}
涉及链表删除操作的时候,稳妥起见都用 dummy node,省去很多麻烦。因为不一定什么时候 head 就被删了。
Copy public class Solution {
public ListNode removeNthFromEnd ( ListNode head , int n) {
ListNode dummy = new ListNode( 0 ) ;
dummy . next = head;
ListNode slow = dummy;
ListNode fast = dummy;
for ( int i = 0 ; i < n; i ++ ){
fast = fast . next ;
}
while ( fast . next != null ){
slow = slow . next ;
fast = fast . next ;
}
slow . next = slow . next . next ;
return dummy . next ;
}
}
这题完全是一个道理,只不过注意下没准要删除的元素是连续的,那种情况下不要动 head.
Copy public class Solution {
public ListNode removeElements ( ListNode head , int val) {
ListNode dummy = new ListNode( 0 ) ;
dummy . next = head;
head = dummy;
while ( head . next != null ){
if ( head . next . val == val){
head . next = head . next . next ;
} else {
head = head . next ;
}
}
return dummy . next ;
}
}
Copy public class Solution {
public void deleteNode ( ListNode node) {
ListNode dummy = new ListNode( 0 ) ;
dummy . next = node;
while ( node . next != null ){
dummy . next . val = node . next . val ;
dummy = dummy . next ;
node = node . next ;
}
dummy . next = null ;
}
}