leetcode 第四弹

本文介绍了如何使用链表结构解决LeetCode中的两数相加问题,包括模拟加法竖式的方法,以及检测环形链表的三种策略:自己写法、哈希表法和龟兔赛跑法。特别提到在处理不同长度链表和环形链表时的技巧和注意事项。
摘要由CSDN通过智能技术生成

2.两数相加

解题思路:看题目意思,得到本体的核心就在于模拟 加法竖式。

方法一:(自己写)

class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        // if(!l1->val) return l2;
        // if(!l2->val) return l1;
        ListNode* a = l1;
        ListNode* b = l2;
        ListNode* head = new ListNode(0);
        ListNode* c = head;
        while (a || b) {
            int n1 = a ? a->val : 0;
            int n2 = b ? b->val : 0;
            int t = n1 + n2 + c->val;

            c->val = t % 10;
            // cout << "c" << c->val << endl;

            if (a)
                a = a->next;

            if (b)
                b = b->next;

            if (a || b || (t / 10 > 0)) {
                cout << "t" << t << endl;
                c->next = new ListNode(t / 10);
            }
            c = c->next;
        }
        return head;
    }
};

巧妙之处:1.两个链表长度不一样,怎么解决?(参考示例三)如果,链表结点存在就返回结点值,否则返回0。

int n1 = a ? a->val : 0;
int n2 = b ? b->val : 0;

2.这一块我觉得是处理最棒的地方。如果a,b未到头肯定要继续创建。还有一种情况,就是最后有高位产生。还有一点,直接让c里面存放进位的值,省了一个变量。

            if (a || b || (t / 10 > 0)) {
                cout << "t" << t << endl;
                c->next = new ListNode(t / 10);
            }

141. 环形链表

方法一: 

思路:建立一维数组,如果访问过,就设为visied【i】==true;如果再访问到visied【i】==true,就说明有环。再想一下,如果便利的话,i++,并不会形成闭环,并且这个还需要建立一位数组,怎么办呢?我们不防直接将访问过得链表的值更改。(当然,这只是投机取巧的方法,实际上,高级代码师,都会保证链表的完整性。)

class Solution {//偷鸡法
public:
    bool hasCycle(ListNode *head) {
        if(!head||!head->next) return false;
        ListNode *p=head;
        while(p){
            if(p->val==10001)
                return true;
            p->val=10001;
            p=p->next;
        }
        return false;
    }
};

 方法二:哈希表法

思路:        我们可以使用哈希表来存储所有已经访问过的节点。每次我们到达一个节点,如果该节点已经存在于哈希表中,则说明该链表是环形链表,否则就将该节点加入哈希表中。重复这一过程,直到我们遍历完整个链表即可。

代码:

public:
    bool hasCycle(ListNode *head) {
        if(!head||!head->next) return false;
        unordered_set<ListNode*> visited;
        ListNode *p=head;
        while(p){
            if(visited.count(p))
                return true;
            visited.insert(p);
            p=p->next;
        }
        return false;

    }
};

语法解释:

方法三:龟兔赛跑法:(经典算法,判断有无环)

假想「乌龟」和「兔子」在链表上移动,「兔子」跑得快,「乌龟」跑得慢。当「乌龟」和「兔子」从链表上的同一个节点开始移动时,如果该链表中没有环,那么「兔子」将一直处于「乌龟」的前方;如果该链表中有环,那么「兔子」会先于「乌龟」进入环,并且一直在环内移动。等到「乌龟」进入环时,由于「兔子」的速度快,它一定会在某个时刻与乌龟相遇,即套了「乌龟」若干圈。

https://assets.leetcode-cn.com/solution-static/141/2.png

class Solution {//龟兔赛跑算法
public:
    bool hasCycle(ListNode *head) {
        if(!head||!head->next) return false;
    
        ListNode *slow=head;
        ListNode *fast=head->next;
        while(slow!=fast){
            if(!fast||!fast->next)
                return false;
            slow = slow->next;
            fast = fast->next->next;
        }
        return true;
        }
};

讲解:为了便于理解,不如现设一个头结点,即起跑线,龟兔同时从该点出发,兔子每次走两步,乌龟每次走一步。如果兔子和乌龟重合说明这条跑道有环。如果,双方没有重合,并且兔子先到达终点,就说明没有环。这样代码就更改如下:

class Solution {//龟兔赛跑算法
public:
    bool hasCycle(ListNode *head) {
        if(!head||!head->next) return false;
        ListNode *dummy=new ListNode(0,head);
        ListNode *slow=dummy;
        ListNode *fast=dummy;

        while(slow!=fast||slow==dummy){
            if(!fast||!fast->next)
                return false;
            slow = slow->next;
            fast = fast->next->next;
        }
        return true;
        }
};

142. 环形链表 II

注意:题目要求  :不允许修改 链表。所以,上一题的第一个做法,pass。

方法一:上一题的哈希表法,可以进行改编。使用哈希表来存储所有已经访问过的节点,同时设置变量记录哈希表中元素数量。每次我们到达一个节点,如果该节点已经存在于哈希表中,则说明该链表是环形链表,返回元素个数-1,即为所求,否则就将该节点加入哈希表中。重复这一过程,直到我们遍历完整个链表即可。

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值