• 剑指offer之链表


    剑指 Offer 52. 两个链表的第一个公共节点

    题目分析:

    我们要在两个链表中找到第一个公共的节点,采用双指针法来实现。我们

             p1先遍历headA,然后遍历headB

              p2 先遍历headB,然后遍历headA

              要是有重合的节点,他们就会相遇

    1. class Solution {
    2. public:
    3. ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
    4. ListNode* p1 = headA;
    5. ListNode* p2 = headB;
    6. /*p1先遍历headA,然后遍历headB
    7. p2 先遍历headB,然后遍历headA
    8. 要是有重合的节点,他们就会相遇*/
    9. while(p1 != p2){
    10. if(p1) p1 = p1 -> next;
    11. else p1 = headB;
    12. if(p2) p2 = p2 -> next;
    13. else p2 = headA;
    14. }
    15. return p1;//返回我们共同节点的节点的指针
    16. }
    17. };

    剑指 Offer 06. 从尾到头打印链表https://leetcode.cn/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof/

    题目分析:

    就是怎么把链表倒着打印输出

    1、使用insert函数倒着插入

    2、使用容器的算法将容器倒着输出

    3、将数据存放到栈里面,然后就可以实现倒着打印

    1. class Solution {
    2. public:
    3. vector<int> reversePrint(ListNode* head) {
    4. vector<int> v1;
    5. while(head){
    6. v1.insert(v1.begin(),head->val);//在v1.begin()位置之前插入字符head—>val,这样就是倒序
    7. head = head ->next;
    8. }
    9. return v1;
    10. }
    11. };
    1. class Solution {
    2. public:
    3. vector<int> reversePrint(ListNode* head) {
    4. vector<int> v1;
    5. while(head){
    6. v1.push_back(head->val);
    7. head = head ->next;
    8. }
    9. return vector<int>(v1.rbegin(),v1.rend());//将容器倒着输出rbegin,rend就是倒序的意思
    10. }
    11. };
    1. class Solution {
    2. public:
    3. vector<int> reversePrint(ListNode* head) {
    4. vector<int> v1;
    5. stack<int>stk;//创建一个栈的容器
    6. while(head){
    7. stk.push(head ->val);//元素入栈
    8. head = head ->next;
    9. }
    10. int len = stk.size();
    11. for( int i = 0; i<len;i++){
    12. v1.push_back(stk.top());//将栈顶元素后插进容器中
    13. stk.pop();
    14. }
    15. return v1;
    16. }
    17. };

    剑指 Offer 22. 链表中倒数第k个节点https://leetcode.cn/problems/lian-biao-zhong-dao-shu-di-kge-jie-dian-lcof/

    题目分析:

    需要我们找到链表的倒数第k个元素,这样我们可以使用双指针法,让两个指针之间的距离相差k个单位,等我们远处的指针指向了链表尾部空的位置,我们近处的指针就是倒数第k个单位

    1. //front与later之间的距离是k,倒数的话就是我们后指针指向空,这样前后指针指向最后k个
    2. class Solution {
    3. public:
    4. ListNode* getKthFromEnd(ListNode* head, int k) {
    5. ListNode* front = head;//近处指针
    6. ListNode* later = head;//远处指针
    7. while (k-- && front != NULL)
    8. front= front->next; // front1 先移动k位
    9. while (front != NULL) { // front与 later同时移动,直到later指向尾端
    10. front = front->next;
    11. later = later->next;
    12. }
    13. return later; // 此时later 就是第k个节点起始位置
    14. }
    15. };

    剑指 Offer 24. 反转链表https://leetcode.cn/problems/fan-zhuan-lian-biao-lcof/

    题目分析:

    我们只需要将指针指向的方向反过来就可以实现

    我们需要将cur指针指向的节点间的指针反向,因为我们cur指针已经被破坏,不能指针利用前进,只能将下一个节点的地址保存起来

     

    1. class Solution {
    2. public:
    3. ListNode* reverseList(ListNode* head) {
    4. ListNode* pre = nullptr;
    5. ListNode* cur =head;
    6. while(cur){
    7. ListNode*later = cur ->next;
    8. cur->next = pre;//指针反转
    9. pre = cur;
    10. cur = later;
    11. }
    12. return pre;
    13. }
    14. };

    21. 合并两个有序链表https://leetcode.cn/problems/merge-two-sorted-lists/

    题目解析:

    我们就好比是球球大作战里面的一个大球,我们面对有两个队伍,先判断哪个队伍前面的最小,就去吃那个,在两个队伍之间反复横跳,吃我一个我们就变胖一些,就这样一直吃完两个队伍

    1. class Solution {
    2. public:
    3. ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
    4. ListNode* preHead = new ListNode(-1);.//吃货节点preHead
    5. ListNode* prev = preHead;
    6. //当两条链表都存在的情况下
    7. while (l1 != nullptr && l2 != nullptr) {
    8. if (l1->val < l2->val) {
    9. prev->next = l1;
    10. l1 = l1->next;//l1的现节点指针移动
    11. } else {
    12. prev->next = l2;//新链表的当前节点指针指向l2
    13. l2 = l2->next;//l2的现节点指针移动
    14. }
    15. prev = prev->next;//吃掉一个节点
    16. }
    17. //下面是只剩下一条或者一条都没有
    18. // 合并后 l1 和 l2 最多只有一个还未被合并完,我们直接将链表末尾指向未合并完的链表即可
    19. prev->next = l1 == nullptr ? l2 : l1;// l1为空的话第三条的指针就指向l2的剩余部分,反之亦然
    20. return preHead->next;//返回第三条链表的第二个节点
    21. }
    22. };

    剑指 Offer 35. 复杂链表的复制https://leetcode.cn/problems/fu-za-lian-biao-de-fu-zhi-lcof/

    题目分析:

    要复制出一个链表

    1、在原来链表的节点之后创建一个空间,并且赋给同样的值,这样的话

    2、随机指针 

    3、next指针,并且把原来的链表去掉,只留下新的复制链表

    1. class Solution {
    2. public:
    3. Node* copyRandomList(Node* head)
    4. {
    5. /*1、复制每个节点,也就是在两个节点之间新建一个节点,复制前驱节点 */
    6. for(auto p = head; p;)//定义一个p,循环执行的条件是p存在
    7. {
    8. auto newp = new Node(p ->val);//创建一个节点,并且赋给val
    9. //在节点之间插入新节点
    10. auto temp = p ->next;//因为我们要在插入一个节点,后面的节点无法通过next指针访问了,只能保存 下一个节点的地址
    11. p ->next = newp;//指针指向新节点
    12. newp ->next = temp;
    13. p = temp;//p跳到下一个要插入的位置之前
    14. }
    15. /*2、开始设置复制节点的random指针*/
    16. for(auto p = head;p; p = p ->next->next)
    17. {
    18. if(p ->random)
    19. {
    20. p ->next->random = p ->random ->next;//random指针的指向
    21. }
    22. }
    23. /*3、从旧链表中分离出我们新生的复制链表,也就是指针只指向我们复制的新生节点*/
    24. Node* dummy = new Node(-1);//头节点
    25. Node* cur = dummy;
    26. for( auto p = head; p; p = p ->next)//p更新
    27. //p是旧链表的指针,cur是新链表的指针
    28. {
    29. cur ->next = p ->next;//p->next就是我们复制生成的节点
    30. cur = cur ->next;//cur更新
    31. p ->next = p ->next ->next;//p指针执行下一个p
    32. }
    33. return dummy->next;
    34. }
    35. };

  • 相关阅读:
    一文了解 io.LimitedReader类型
    常用设计模式总结 + 实例
    C++ std::thread 线程创建和启动
    Python中list的操作4-3
    星戈瑞Annexin V-FITC细胞凋亡检测试剂盒
    vue3自定义指令的学习和常用的几个自定义指令
    【ElasticSearch】ElasticSearch常用查询api集合(一)
    Hadoop-3.0.0版本Windows安装
    docker快速建立samba、vsftp文件共享
    【观察】OpenHarmony:技术先进“创新局”,持续创新“谋新篇”
  • 原文地址:https://blog.csdn.net/qq_43448818/article/details/126441951