24. 两两交换链表中的节点
思路:
- 递归:由于只要两两交换,设原链表的头结点为head,第二个节点为nexthead(head.next)。所以只要把nexthead调用递归直到递归完成,再head.next指向head,最后返回nexthead(此时为头节点)就实现两两互换。
- 迭代:直接画图比文字好理解多。每次交换最后记得把temp指向temp.next。
C#代码:
//递归
public class Solution {
public ListNode SwapPairs(ListNode head) {
if(head == null || head.next == null)return head;
ListNode nexthead = head.next;
head.next = SwapPairs(nexthead.next);
nexthead.next = head;
return nexthead;
}
}
//迭代
public class Solution {
public ListNode SwapPairs(ListNode head) {
if(head == null || head.next == null)return head;
ListNode dummyhead = new ListNode(0,head);
ListNode temp = dummyhead;
while(temp.next != null && temp.next.next != null){
ListNode temp1 = temp.next;
ListNode temp2 = temp.next.next;
temp.next = temp2;
temp1.next = temp2.next;
temp2.next = temp1;
temp = temp1;
}
return dummyhead.next;
}
}
19.删除链表的倒数第N个节点
19. 删除链表的倒数第 N 个结点 - 力扣(LeetCode)
思路:利用双指针解决,因为是删除倒数的第N个节点,然后相当于快指针指向null,慢指针指向目标节点,快慢指针相差N。可以先让快指针指向head之后的n个节点,再同时移动快慢指针就能使慢指针指向目标节点。
C#代码:
public class Solution {
public ListNode RemoveNthFromEnd(ListNode head, int n) {
ListNode dummyhead = new ListNode(0,head);
ListNode f = dummyhead;
ListNode l = dummyhead;
for(int i = 0;i < n;i++){
f = f.next;
}
while(f.next != null){
f = f.next;
l = l.next;
}
l.next = l.next.next;
return dummyhead.next;
}
}
面试题02.07. 链表相交
面试题 02.07. 链表相交 - 力扣(LeetCode)
思路:双指针法,分别在指向两个链表的头结点,然后一直循环,有指针到null就指向另一个链表,直到两个指针指向元素相同或者同时指向null,跳出循环,输出其中一个指针。(还有灵位的方法用哈希表记录其中一个链表,然后另一个链表去遍历,其中哈希表有就跳出)
C#代码:
//双指针
public class Solution {
public ListNode GetIntersectionNode(ListNode headA, ListNode headB) {
ListNode pointer1 = headA,pointer2 = headB;
while(pointer1 != pointer2){
pointer1 = pointer1 == null?headB:pointer1.next;
pointer2 = pointer2 == null?headA:pointer2.next;
}
return pointer1;
}
}
142.环形链表II
思路:主要两个点,如何判断是否有环,以及有环怎么找到入口。是否有环可以利用快慢指针一直遍历,只要指向相同,即有环,否则没有环;怎么找到入口,也是靠双指针,一个指向原来快慢指针的指向元素,另一个从起点开始,之后一直循环直到两指针相同。
(具体找到入口的演示:代码随想录 (programmercarl.com),简单两句话说不清楚)
C#代码:
public class Solution {
public ListNode DetectCycle(ListNode head) {
ListNode f = head,s = head;
while(f != null && f.next != null){
f = f.next.next;
s = s.next;
if(f == s){
ListNode index1 = f;
ListNode index2 = head;
while(index1 != index2){
index1 = index1.next;
index2 = index2.next;
}
return index1;
}
}
return null;
}
}
总结:今天链表的这四道题都没啥思路,得去看视频或者解答才知道怎么写出来。不过每道题写完后都可以完全理解,之后还是得好好二刷一遍。还有一点,写完对比才发现链表相交和环形链表这两道题的思路可以说差不多,都可以用双指针直接遍历出结果。