首页 > 其他分享 >代码随想录-链表

代码随想录-链表

时间:2023-11-23 20:14:48浏览次数:46  
标签:ListNode cur val int nullptr 代码 随想录 next 链表

203.移除链表元素

https://leetcode.cn/problems/remove-linked-list-elements/description/
image

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        //先删头节点
        while(head != nullptr && head->val == val)
        head = head->next;

        ListNode* cur = head;
        while(cur != nullptr && cur->next != nullptr)
        {
            if(cur->next->val == val)
            cur->next = cur->next->next;

            else                //这里else是为了保证,比如1 2 2 1,删完第一个2,如果直接后移cur,就不会判断第二个2了
            cur = cur->next;
        }
        return head;
    }
};

707. 设计链表

https://leetcode.cn/problems/design-linked-list/
image

class MyLinkedList {
public:
    struct Node {
        int val;
        Node *next;
        Node() : val(0), next(nullptr) {}
        Node(int x) : val(x), next(nullptr) {}
        Node(int x, Node *next) : val(x), next(next) {}
    };
    Node *dummyhead;
    int size;                       //size表示链表一共有几个元素,所以最大索引是size-1
    MyLinkedList() {
        dummyhead = new Node();
        size = 0;
    }
    int get(int index) {
        if(index < 0 || index >= size)      //保证一定可以获取到正确的索引位置的val
            return -1;
        Node* cur = dummyhead->next;        //cur从头节点开始,遍历index次
        while(index--)
            cur = cur->next;
        return cur->val;
    }
    void addAtHead(int val) {
        Node* node = new Node(val);
        node->next = dummyhead->next;
        dummyhead->next = node; 
        size++;
    }
    
    void addAtTail(int val) {
        Node* node = new Node(val);
        Node* cur = dummyhead;
        while(cur->next != nullptr)         //跑到尾,现在的cur就是最后一个节点
            cur = cur->next;
        cur->next = node;
        size++;
    }
    void addAtIndex(int index, int val) {
        if(index > size)                    //为什么没等号,比如一共三节点,在索引3前加就是尾插的意思,至于负数统统看成头插
            return;
        Node* node = new Node(val);
        Node* cur = dummyhead;              //需要锁定index索引的前一个,因为要求插入第index个的前一个
        while(index--) 
            cur = cur->next;

        node->next = cur->next;
        cur->next = node;
        size++;
    }
    void deleteAtIndex(int index) {
        if(index < 0 || index >= size)      //保证一定可以找到正确的索引位置的val
            return;
        Node* cur = dummyhead;              //保证找到index-1索引处的值

        while(index--) 
            cur = cur->next;

        Node* del = cur->next;
        cur->next = del->next;
        delete del;
        size--;
    }
};

/**
 * Your MyLinkedList object will be instantiated and called as such:
 * MyLinkedList* obj = new MyLinkedList();
 * int param_1 = obj->get(index);
 * obj->addAtHead(val);
 * obj->addAtTail(val);
 * obj->addAtIndex(index,val);
 * obj->deleteAtIndex(index);
 */

206.翻转链表

https://leetcode.cn/problems/reverse-linked-list/description/
image

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if(head == nullptr || head->next == nullptr) 
            return head;

        //思路 用temp记录当前的后面所有节点,即temp->next = remain,现在temp和cur都指向了remain,
        //就可以断掉cur->next,让cur指向它前面的那个,也就是cur->next = pre; 接下来,temp cur pre都后移一个,继续操作。
        ListNode* pre = nullptr;
        ListNode* cur = head;
        //ListNode* temp = cur;
        ListNode* temp = cur->next;
        while(cur != nullptr)
        {
            // cur->next = pre;        //这一步实际上改变了原链表的结构,所以temp->next也找不到了!!!!
            // pre = cur;
            // cur = temp->next;
            // temp = cur;
            cur->next = pre;        
            pre = cur;
            cur = temp;
            if(temp != nullptr)
            temp = cur->next;

        }
        return pre;
    }
};

19.删除链表的倒数第N个节点

https://leetcode.cn/problems/remove-nth-node-from-end-of-list/
image

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        //好妙的双指针,移动快指针直至快慢差n,一起移动,快指针到结尾了,说明该删除慢指针了
        //这里需要推算一下,当fast是倒一了,比如要删除倒3,实际上他们之间只隔了1!但是为了方便删除,需要找到倒4操作!!!
        ListNode* dummyhead = new ListNode();
        dummyhead->next = head;
        ListNode* slow = dummyhead;
        ListNode* fast = dummyhead;
        
        //令fast等于第n-1索引的位置
        //题目已经说了n的范围合法!!不用判断!!
        for(int i = 0; i < n; i++)
            fast = fast->next;
        
        //现在slow和fast隔了n-1个,只要fast移到最后,slow的位置就是要删除的前一个,让这个的next跳过下一个即可
        while(fast->next!=nullptr)
        {
            fast = fast->next;
            slow = slow->next;
        }
        ListNode* del = slow->next;
        slow->next = slow->next->next;
        delete del;

        return dummyhead->next;
    }
};

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

https://leetcode.cn/problems/swap-nodes-in-pairs/description/
image

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        if(head == nullptr || head->next == nullptr)
        return head;

        ListNode* cur = new ListNode();
        cur->next = head;
        ListNode* res = cur;
        while(cur->next!=nullptr && cur->next->next!=nullptr)
        {
            ListNode* tmp1 = cur->next;
            ListNode* tmp2 = cur->next->next;

            // cur->next = tmp2;
            // tmp2->next = tmp1;    
            //这样写会导致死循环。第一行表示剔除tmp1,第二行表示tmp2指向tmp1,而tmp1又指向tmp2,它应该指向tmp2下一个

            cur->next = tmp2;
            tmp1->next = tmp2->next;
            tmp2->next = tmp1;

            cur = cur->next->next; //实际上就是tmp2->next,也是tmp1->next
        }
        return res->next;
    }
};

链表相交

https://leetcode.cn/problems/intersection-of-two-linked-lists-lcci/description/
image

class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        //k神的解法,A全部+B公共以前 = B全部+A公共以前
        ListNode* A = headA;
        ListNode* B = headB;
        while(A!=B)
        {
            //相当于if(A!=nullptr)   A = A->next; else A = headB
            A = A != nullptr? A->next : headB;
            B = B != nullptr? B->next : headA;
        }
        return A;
    }
};

142.环形链表

https://leetcode.cn/problems/linked-list-cycle-ii/description/
image

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        //fast一次走两步,slow一次走一步,他们在环内相遇,如果到末尾还没相遇就是没有环,
        // fast - slow = nb, fast = 2*slow ==> slow = nb, fast = 2nb!!!
        // 一步一步地走,必然可以停留在入口处,slow = nb  想办法让他再走a步,就可以找到入口!
        // 相遇后,fast回到起点,一次走一步走a步,slow跟着走a步,二者再次相恰好是环入口

        /*重点:① 二者第一次相遇 slow = nb
                ②  不管一次几步,只要走了a + mb步一定停在入口处,只是一次两步可能永远找不到m!(b = 4 a = 3 a+mb必然是奇数)
        */
        ListNode* fast = head;
        ListNode* slow = head;
        //while(fast != slow)         //不要这样写,,因为初始的时候俩都是head,根本不会进入循环。。。。
        while(true)
        {
            if(fast == nullptr || fast->next == nullptr)    //这里顺序也有讲究的。。如果输入一个空链表,访问fast->next是错误的
            return nullptr;

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

            if(fast == slow) 
            break;
        }

        fast = head;
        while(slow != fast)
        {
            slow = slow->next;
            fast = fast->next;
        }
        return fast;
    }
};

标签:ListNode,cur,val,int,nullptr,代码,随想录,next,链表
From: https://www.cnblogs.com/xsl-blogs/p/17852367.html

相关文章

  • 反转链表系列问题
    反转链表系列问题作者:Grey原文地址:博客园:反转链表系列问题CSDN:反转链表系列问题反转单链表题目描述见:LeetCode206.ReverseLinkedList思路如下对于任何一个节点cur来说,记录一个前驱节点pre(第一个节点的前驱节点是null)先用一个临时节点tmp记录cur的下一个......
  • 代码随想录-数组
    704.二分查找https://leetcode.cn/problems/binary-search/description/classSolution{public:intsearch(vector<int>&nums,inttarget){intleft=0;intright=nums.size()-1;while(left<=right){......
  • 软件开发费用是多少?验收时看看有没有这些代码!
    在当今时代,软件开发已经成为企业竞争的关键因素之一,然而,许多企业在面对软件开发时,往往会面临一个问题:软件开发费用是多少?验收时又该如何检查这些代码呢?本文将为你解答这些问题,并分享一些基础的代码知识。一、软件开发费用是多少?首先,我们需要明白软件开发费用的影响因素有很多,包......
  • Springboot文件上传代码笔记
    1.在src下创建filter包,包内Class名UploadFilterpackagecom.gd.filter;importorg.apache.catalina.servlet4preview.http.HttpServletRequest;importjavax.servlet.*;importjavax.servlet.annotation.WebFilter;importjavax.servlet.http.HttpServletResponse;impor......
  • 低代码表单设计器:可视化+灵活+易操作,降本增效轻松实现!
    在现代化办公环境中,拥有先进的低代码表单设计器,可以让企业降本又增效,节约企业成本的同时,也能高效利用企业内部资源,为实现数字化转型升级提供夯实根基。那么,低代码表单设计器拥有什么样的特点?每种特点的优势表现在哪里?通过这篇文章,我们一起了解灵活、易操作、可视化的低代码表单设......
  • 快手视频作品评论区提取工具,可采集UID,真实ID,评论内容开源版!基础代码
    之前给客户定制了一个提取视频评论区用户数据的功能,这个就是POST抓包解密形式的,所以都是公开的的,网页端提取,输入视频链接导入COOKIE【浏览器F12可提取COOKIE】就能自动提取作品下的所有评论内容用户di等信息,我这边直接把所有源码都分享出来。设计界面:  COOKIE输入:【浏览器F......
  • 直播系统源代码,vue实现无缝滚动
    直播系统源代码,vue实现无缝滚动一、采用js的方法实现 <template><div><divclass="box"><divv-for="itemin2"class="item-box":style="{transform:'translate(0,'+scrollTop+'px)'}"><divclass=&......
  • 上传本地代码到GitHub
      上传本地代码到GitHub在创建完成仓库后,接下来就是上传本地代码到GitHub上。先在本地创建一个文件夹作为本地Git仓库,然后使用Git添加文件并提交。在、在命令行中,进入本地仓库文件夹中,执行以下命令来添加代码:#初始化本地Git仓库gitinit#添加所有文件至Git仓库中gitad......
  • VS 调试 提示 Lc.exe已退出 代码为-1问题解决方法
    找到程序项目下Properties文件夹licenses.licx文件,然后右键选择删除就可以了,调试运行正常了 https://jingyan.baidu.com/article/b24f6c822592b686bfe5daac.html......
  • springboot多文件上传代码实例及解析
    这篇文章主要介绍了springboot多文件上传代码实例及解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下一说明spingMVC支持文件上传,我们通过Apach的commons-fileupload包的CommonsMultipartResolver去实现了spingMVC的Mu......