力扣第四天----第24题、第19题、第142题、面试0207

力扣第四天----第24题、第19题、第142题、面试0207

一、第24题–两两交换链表中的节点

​ 链表的题,做到现在都是使用了dummyhead。这题中,每隔两个交换一次→设置2个临时变量存储指针,便于交换操作,再配合cur = cur->next->next移动指针。

class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        ListNode* dummyhead = new ListNode(0);
        dummyhead->next = head;
        ListNode* cur = dummyhead;
        while((cur->next != nullptr) && (cur->next->next != nullptr)){ //这里注意,
 //要把(cur->next != nullptr) 放在前面判断,通过了再判断(cur->next->next != nullptr),避免出现空指针。
            ListNode* tempn1 = cur->next;
            ListNode* tempn2 = cur->next->next->next;
            cur->next = tempn1->next;
            tempn1->next = tempn2;
            cur->next->next = tempn1;
            cur = cur->next->next;
        }
        return dummyhead->next;
    }
}

二、第19题–删除链表的倒数第 N 个结点

​ 也是用到了dummyhead。这道题类似于前几天做过的"第209题–长度最小的子数组",使用双指针的间距表达窗口长度。两个while的判定条件要注意。

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode* dummyhead = new ListNode(0);
        dummyhead->next = head;
        ListNode* fast = dummyhead;
        ListNode* slow = dummyhead;

        n++;
        while(n--){             //这里要使fast移动n+1次,因为删除操作要使slow移动到第N个节点的前一节点。
            fast = fast->next;
        }
        while(fast != nullptr){ //注意不要出现空指针,使用fast!=nullptr还是fast->next!=nullptr要注意,可以代入特殊情况试一下。
            fast = fast->next;
            slow = slow->next;
        }
        slow->next = slow->next->next;
        return dummyhead->next;
    }
};

三、第142题–环形链表 II

​ 链表里遇到的最复杂的题,一共用到三个指针----用快慢指针去寻找相遇的点,用第3个指针去找循环开始的节点(结合快慢指针的结果)。

​ 吐槽一下:判断是否是循环链表,考查的知识点就都考查到了。求循环节点起始位置的方法,就像小学数学题,没体现出新的链表知识点、也不是多高级的数学证明,也就能考查下逻辑能力。真是没意愿搞这个小学数学题,纯纯地没必要,看了下答案写上去的。

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        ListNode *fast = head;
        ListNode *slow = head;
        ListNode *chase = head;

        while (fast != nullptr){        //空指针判断,如果空了,直接返回nullptr
            slow = slow->next;
            if (fast->next == nullptr){ //下一个节点的空指针判断,如果空了,直接返回nullptr。每次循环fast移动两次,所以要判断两个位置是否为空指针。
                return nullptr;
            }
            fast = fast->next->next;    //每次循环,快指针移动两次,慢指针移动一次,如果有循环的话就会相遇,即触发下面if条件。
            if(fast == slow){
                while(chase != slow){   //用第三个指针和当前的慢指针再次去相遇,如果相遇了,一定会是循环起始节点。触发跳出循环的条件,就是返回节点。
                    chase = chase->next;
                    slow = slow->next;
                }
                return chase;
            }
        }
        return nullptr;
    }
};

四、面试0207–链表相交

​ 两个链表组合起来,A+B和B+A,两个指针分别从各自的head遍历,直到这两个节点相等。因为存在相交的情况,在A+B或者B+A的末端,存在相等的情况。

有一些细节要注意----一个链表为空的情况;链表循环结束,手动移动指针到另一个链表。

class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        ListNode* nodeA = new ListNode(0);
        nodeA = headA;
        ListNode* nodeB = new ListNode(0);
        nodeB = headB;   

        if((headA == nullptr) || (headB == nullptr))  //节点为空的情况处理。
            return nullptr;
        else{
            while(nodeA!=nodeB){     //两节点不相等时一直循环下去,到最后一定会相等的。如果不存在相交情况,
            //循环最后nodeA和nodeB都是nullptr,也是相等的。
                if (nodeA == nullptr)   //如果到了末尾,读到空指针时,手动设置nodeA的位置为headB,从另一个链表继续遍历。
                    nodeA = headB;
                else					//正常情况,没到末尾,nodeA移动到下一节点。
                    nodeA = nodeA->next;
                if (nodeB == nullptr)
                    nodeB = headA;    
                else
                    nodeB = nodeB->next;
            }
            return nodeA;
        }   
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值