代码随想录第三天

今天又把昨天卡了很久的设计链表题 试试能不能说是用不带长度的去写出来 但是试了很久就失败了 因此以后就用带长度的做就行了。 目前没办法用不带长度的做出来,以后可能实力强了再说吧

今天的第一题 虽然是二刷但是刚开始还是没思路 不知道怎么换 其实是要引入虚拟头结点 

注意啊 注意 1 你引入了虚拟头结点后要把它的next置为头结点 这样才算成功引入了。

2这道题有一个关键就是 你pre指向的是prehead的话 那么再下一次挪的话 你还得是指向pre那个元素 而不能向后指一位  总体而言这个题就是引入了一个prehead 没什么难的 

class Solution {

public:

    ListNode* swapPairs(ListNode* head) {

        ListNode* prehead=new ListNode();

        prehead->next=head;

        ListNode* pre=prehead;

        ListNode* p=prehead->next;

        ListNode* tem;

        while(p!=NULL&&p->next!=NULL){

            pre->next=p->next;

            tem=p->next;

            p->next=p->next->next;

            tem->next=p;

            pre=p;

           

            p=pre->next;

            

        }

        head=prehead->next;

        delete prehead;

        return head;

    }

};

它要是给你一个链表那就不能用size了 如果是让你去设计一个链表 那完全可以用加个size.

3现在还有个问题就是你要注意代码的边界问题 你要说是把代码写在规定的地方。

第二个题 删除链表的倒数第N个结点 二刷 几乎一遍过 就是想明白就行 不要遗留问题:

class Solution {

public:

    ListNode* removeNthFromEnd(ListNode* head, int n) {

        ListNode* prehead=new ListNode();

        prehead->next=head;

        ListNode* slow=prehead,*fast=prehead;

        for(int i=1;i<=n+1;i++)

        fast=fast->next;

        while(fast!=NULL){

            slow=slow->next;

            fast=fast->next;

        }

        ListNode* tem=slow->next;

        slow->next=slow->next->next;

        delete tem;

        head=prehead->next;

        delete prehead;

        return head;

    }

        

};

还有一个问题是你没底的原因还是在于练的少 如果你基本提交一次过 那肯定就很有底了 不过不用着急 就是按着事情发生走就行 焦虑以后的事情完全没意义

第二道题 链表相交 

二刷 几乎一遍过

唯一注意的一点就是 你在用ListNode *A=headA,*B=headB; 这么去用的时候 不能写成ListNode *A=headA,ListNode*B=headB; 这样不行 因为你要去连着定义 你就不能用两个Listnode类型。

其他没有什么 简单的小题

class Solution {

public:

    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {

        ListNode *A=headA,*B=headB;

        int a=0,b=0;

        for(;A!=NULL;a++){

            A=A->next;

        }

        for(;B!=NULL;b++)

            B=B->next;

            A=headA;

            B=headB;

        if(a>=b){

            for(int i=a-b;i>0;i--)

            A=A->next;

        }

        else{

            for(int i=b-a;i>0;i--)

            B=B->next;

        }

        while(A!=NULL&B!=NULL){

            if(A==B){

                return A;

            }

            A=A->next;

            B=B->next;

        }

        return NULL;

    }

};

第四题:

环形链表 这就是纯纯的数学题 虽然是第二次刷了 但是那些公式还是不好背

就是得背公式。

首先一个点是: 就是让快指针走两步 慢指针走一步 这样就肯定能在环里相遇 (如果没环的话 慢指针永远追不上快指针 所以肯定是在环里相遇)

第二个点是:相遇的位置怎么确定 

这个公式肯定还是得自己推一下 不然根本记不住

其实主要关系就是fast走过的路=slow走过的路*2

但与其说去推公式 那太慢了 总而言之就是 因为fast是slow的两倍 所以你一定能找到他们相遇的结点 那么你得到一个相遇的结点 那么再去用从相遇结点出发和从起始结点出发的指针 再去相遇就是起始结点了 因为x=z 其他无非是再去转几圈

注意1 只有一个结点不会成环

2还有一个问题是一开始fast和slow是相等的 都指向第一个结点 所以循环根本不会执行 这里是个问题 因此要先赋值

3do {}while(); 要在最后whie的括号后面加分号 注意!!!

4还有一个问题就是你在判断是否为空上 如果你(fast==NULL&&fast->next==NULL)用这么去判断的话 那个如果fast为空 你还是会出错 所以只能说是分开 从循环中去判断  不是说你要去分开去判断  而是你这里应该用的是|| 而不是&& 因为是两个只要有一个满足就可以  

另外也不用担心 因为:

你的观察是正确的。在C++中,如果一个指针是 NULL,试图通过这个指针访问成员会导致未定义行为,通常会导致程序崩溃。

逻辑或操作符 || 在C++中有一个“短路”行为。如果 || 左边的表达式为 true,那么 || 右边的表达式就不会被求值。所以在 if(head==NULL || head->next==NULL) 这行代码中,如果 headNULL,那么 head->next 不会被访问,就不会出错。

有一个短路行为。

二刷 还是基本几次过的 还是简单的小题 主要就是要搞清楚||和&&的区别 和 一开始它们都相等 所以要先去移动指针 再去做比较。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值