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;
}
}