代码随想录算法训练营第四天|24. 两两交换链表中的节点、19.删除链表的倒数第N个节点、面试题02.07. 链表相交、142.环形链表II

24. 两两交换链表中的节点

24. 两两交换链表中的节点 - 力扣(LeetCode)

思路:

  • 递归:由于只要两两交换,设原链表的头结点为head,第二个节点为nexthead(head.next)。所以只要把nexthead调用递归直到递归完成,再head.next指向head,最后返回nexthead(此时为头节点)就实现两两互换。代码随想录算法训练营第四天|24. 两两交换链表中的节点、19.删除链表的倒数第N个节点、面试题02.07. 链表相交、142.环形链表II_第1张图片
  • 迭代:直接画图比文字好理解多。每次交换最后记得把temp指向temp.next。代码随想录算法训练营第四天|24. 两两交换链表中的节点、19.删除链表的倒数第N个节点、面试题02.07. 链表相交、142.环形链表II_第2张图片

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

142. 环形链表 II - 力扣(LeetCode)

思路:主要两个点,如何判断是否有环,以及有环怎么找到入口。是否有环可以利用快慢指针一直遍历,只要指向相同,即有环,否则没有环;怎么找到入口,也是靠双指针,一个指向原来快慢指针的指向元素,另一个从起点开始,之后一直循环直到两指针相同。

(具体找到入口的演示:代码随想录 (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;
    }
}

总结:今天链表的这四道题都没啥思路,得去看视频或者解答才知道怎么写出来。不过每道题写完后都可以完全理解,之后还是得好好二刷一遍。还有一点,写完对比才发现链表相交和环形链表这两道题的思路可以说差不多,都可以用双指针直接遍历出结果。

你可能感兴趣的:(代码随想录,算法)