24
这道题不算难,我们先看看我的一个解法
我的思路是这样,一个个遍历,遇到flag是2呢就交换,下面这个过了,但是有个陷阱是踩了的,就是一开始忘记加黄色的那个代码。
public ListNode swapPairs(ListNode head) {
if(head == null){
return null;
}
ListNode mockNode = new ListNode();
mockNode.next = head;
ListNode prePreNode = null;
ListNode preNode = mockNode;
ListNode nextNode = null;
int flag = 1;
while(head != null){
print(mockNode);
if(flag==1){
//当前是配对1
flag=2;//下次是配对2
prePreNode = preNode;
preNode = head;
}else{
prePreNode.next = head;
//先记着自己的下一个
nextNode = head.next;
//自己指向前一个
head.next = preNode;
//前一个的指向nextNOde
preNode.next = nextNode;
flag=1;//下一次又是配队1
head = head.next; //赶紧把head转掉
preNode = head;
prePreNode = prePreNode.next;
}
head = head.next;
}
return mockNode.next;
}
为什么不加黄色那段代码有问题?我们看看。
本来第一次转完看上去很完美[p2就是prepreNode指针,h就是head指针,p就preNode指针]:
看到没,当前head指向2,但是pre指向的1却在2的后面!也就是说下次遍历head.next又特么遍历1这个节点去了而不是去遍历3这个节点,所以要加那两个代码:
head = head.next; //赶紧把head转掉
preNode = head;
上面可能flag比较丑,可以避免也就是head = head.next.next。。。。但是你咋知道head.next不是null呢,所以人家这么写:(恩。。还是flag好理解吧。。。。运行时间其实没差多少)
然后是leetcode19
这道题我第一反应是hashMap存进去然后最后n个的来删。
但是吧,浪费存储。。。
双指针就搞定了,快的和慢的中间间隔为n。最后跑完,慢的指向第n个的前一个,快的指向最后一个不就可以了,ps:虚拟节点确实好用。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode mockNode = new ListNode(); //上虚拟节点
mockNode.next = head;
ListNode slow = mockNode;
ListNode fast = mockNode;
int cnt = 0;
while(fast.next != null){
fast = fast.next;
cnt++;
if(cnt>n){
slow = slow.next;
}
}
slow.next = slow.next.next;
return mockNode.next;
}
}
然后再说一个。。。现在确实拿到链表就想写
while(head!=null){
。。。
head = head.next;
}