代码随想录算法训练营第四天|两两交换链表节点、删除链表的倒数第N个节点、链表相交、环形链表II

1.题目:leetcode24
主要思路:重要的点在于首先构造一个虚拟节点,然后分三步交换节点
三步交换
同时,自己实践的时候要注意判断空指针异常可能的情况,当节点数是单数,当节点数是双数,因为此时会有两种情况判断,不注意就会导致空指针异常。
代码如下:

class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        ListNode* dummyhead = new ListNode(0);
        dummyhead->next = head;
        ListNode* cur = dummyhead;
        while(cur->next!=NULL && cur->next->next !=NULL){
            ListNode* tmp = cur->next->next->next;
            ListNode* tmp1 = cur->next;
            cur->next = cur->next->next;
            cur->next->next = tmp1;
            cur->next->next->next = tmp;

            cur = cur->next->next;
        }
        return dummyhead->next;
    }

};

2.题目:leetcode19
主要思路:没听课之前采用的方式是用了三个指针,后面听了课换成了双指针操作,代码如下:

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        if(head==NULL) return NULL;
        else{
            ListNode* later = head;
            ListNode* del = head;
            int count = n;
            while(later&&count!=0){
                later = later->next;
                count--;
            }
            later = later->next;
            if(count!=0){
                return NULL;
            }else{
                while(later){
                    later = later->next;
                    del = del->next;
                }
                del->next = del->next->next;
            }
        }
        return head;
    }
};

不知道为什么还是不对,暂时没改出来。
3.
leetcode160
思路:这是一道链表相交的题,最常见的方法,就是遍历两个链表,根据其长度,选出长链表,并把长链表遍历到与短链表同等长度的地方,然后同时一起遍历,即可查出相交点。
代码如下:

class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        ListNode* nodeA = headA;
        ListNode* nodeB = headB;
        int a_length = 0,b_lenght =0;
        while(nodeA){
            nodeA = nodeA->next;
            a_length++;
        }
        while(nodeB){
            nodeB = nodeB->next;
            b_lenght++;
        }
        nodeA = headA,nodeB = headB;
        while(a_length>b_lenght){
            headA = headA->next;
            a_length--;
        }
        while(b_lenght>a_length){
            headB = headB->next;
            b_lenght--;
        }
        while(headA!=headB && headA!=NULL && headB!=NULL){
            headA = headA->next;
            headB = headB->next;
        }
        if(headA)
            return headA;
        else if(headB)
            return headB;
        else
            return NULL;
    }
};

4.环形链表II:
题目:leetcode142
主要思路:

这道题感觉像一个数学问题,用快慢指针同时前进,并把入口点、出发点、相遇点随机设置出来,快指针前进速度是慢指针的2倍,因此有(x+y)*2 = x+(y+z)*n 化解可得 x = (n-1) * (y+z)+z,所以可知在快慢节点相遇后,当 n为1的时候,公式就化解为 x = z,

这就意味着,从头结点出发一个指针,从相遇节点 也出发一个指针,这两个指针每次只走一个节点, 那么当这两个指针相遇的时候就是 环形入口的节点。n如果大于1,就是fast指针在环形转n圈之后才遇到 slow指针。其实这种情况和n为1的时候 效果是一样的。

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        ListNode* fast = head;
        ListNode* slow = head;
        while(fast != NULL && fast->next != NULL) {
            slow = slow->next;
            fast = fast->next->next;
            // 快慢指针相遇,此时从head 和 相遇点,同时查找直至相遇
            if (slow == fast) {
                ListNode* index1 = fast;
                ListNode* index2 = head;
                while (index1 != index2) {
                    index1 = index1->next;
                    index2 = index2->next;
                }
                return index2; // 返回环的入口
            }
        }
        return NULL;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值