首页 > 其他分享 >day20

day20

时间:2022-11-17 21:35:57浏览次数:45  
标签:slow ListNode int nullptr day20 fast next

【0206.翻转链表】

/**
 * 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) {
        ListNode *slow = nullptr;
        ListNode *fast = head;
        while (fast != nullptr) {
            ListNode * temp = fast->next;
            fast->next = slow;
            slow = fast;
            fast = temp;
        }
        return slow;
    }
};
  • 较快,一遍过

    • 在slow 和 fast赋值初值的时候 考量较久 最后发现slow赋值空指针 而不是一贯的假头指针 fast赋值头指针 并且fast!=nullptr 而不是fast->next!=nullptr

    • 也考量片刻 链表初始为空的情况 那么这个时候返回slow指针也是空 符合情况 因此不需要多余的操作

  • 对比卡哥 思路代码基本一致

    • 注意一点 while (fast != nullptr){...} 也可以等价写成while (fast){...}

【0019.删除链表的倒数第N个节点】

/**
 * 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:
    int countNode(ListNode *head) {
        ListNode *fast = head;
        int sum = 0;
        while(fast) {
            sum++;
            fast = fast->next;
        }
        return sum;
    }
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        int sum = countNode(head);
        //sum == 5  n==2  deleteTarget == 5 - 2  beforeDeleteTarget == 5 - 3 == sum - n - 1 
        ListNode *shead = new ListNode(0, head);
        ListNode *fast = shead;  
        int i = -1;
        while (fast) {
            if (i == (sum - n - 1)) {
                ListNode *temp = fast->next;
                fast->next = temp->next;
                delete temp;
            }
            fast = fast->next;
            i++;
        }
        return shead->next;
    }
};
  • 较慢,算是 一遍过

    • 主要思路 把倒数第n个结点 转换为 正数第 sum - n个结点 那么必然需要找到该节点前面紧跟的结点 即下标为 sum - n - 1 (默认下标从0开始)。 这里的分析思路 还是值得学习的 具体见代码注释部分!!

    • 此外 对主函数 中如果有分任务 那么写成子函数由主函数去调用完成 会看起来代码更易读

    • 设置头结点 除了统一操作 这里的一个作用 是方便返回链表 即return shead->next; 即可

  • 问题出在 while循环的结束条件 一开始写的是while (fast->next != nullptr) {...} 但其实循环结束条件可以先不着急写上去 或者先暂时写上去 总之在写完循环体之后是需要检查循环结束条件的 那么重点来了 怎么检查呢 这个问题很好 在我看来 从循环体执行结果 得到结束条件 再把这个结束条件拿去和之前暂时写下的结束条件对比即可 ——如果符合 那么后者不变 如果不符合 那么改变后者

    • 比如
      • 一开始 我不写 或暂时写 结束条件为 while (fast->next != nullptr) {...}
      • 经过多次执行循环体会先得到 fast == nullptr 所以此时结束条件应该是while(fast != nullptr)
      • 对比之前暂时写的 是不正确的 需要改变
      • 因为先得到fast == nullptr 所以如果是此时fast->next就相当于nullptr->next 这是会报错的
  • 对比卡哥思路 我竟然又完全没想到这个思路 可以说 我上面的代码并不是双指针法

    • 卡哥思路:如果要删除倒数第n个节点,让fast移动n步,然后让fast和slow同时移动,直到fast指向链表末尾。删掉slow所指向的节点就可以了

    • 为什么呢 我思考了一下

      • 删除倒数第n个结点 因为链表的单向性 所以这个问题 并不等同于删除正数第n个结点 不能通过一个循环 或者说一个指针就可以删除 但是双指针就可以一个循环解决!

      • fast先移动n步(fast先移动距离)

      • 接下来fast从第n+1步到结尾结点之间这一段距离(fast后移动的距离) 让slow随之从0开始移动(slow先移动的距离) slow随fast开始而开始 随fast停止而停止

      • 因为

        • fast先移动距离 + fast后移动距离 == 总长度

        ​ slow先移动距离 + slow后移动距离 == 总长度

        • 因为 fast后移动距离 == slow先移动距离
        • 所以 fast先移动距离 == slow后移动距离==删除倒数第n个元素需要特别移动的那一段距离长度
    • fast指针 遍历元素 控制节奏 slow指针 指向实际构成新结构体(如数组、链表等等)的元素

  • 以后还需要再看看 重写卡哥思路代码

标签:slow,ListNode,int,nullptr,day20,fast,next
From: https://www.cnblogs.com/deservee/p/16901057.html

相关文章

  • day20221110今天学了什么?前端学习网站
    零基础开始学Web前端开发,有什么建议吗?-瑾瑜的回答-知乎https://www.zhihu.com/question/19637373/answer/2434134730前端学习路线(推荐视频)-前端小通的文章-知......
  • 牛客java选择题每日打卡Day20
    牛客java选择题每日打卡Day20......
  • 代码随想录Day20
    LeetCode104.找出二叉树最大深度给定一个二叉树,找出其最大深度。二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。说明:叶子节点是指没有子节点的节点。示......
  • java_day20~22
    Java基础GUI编程核心技术:Swing、AWT现在GUI并不流行因为其界面不美观、需要依赖jre环境事件监听意为:当某个事情发生的时候,要干什么/***事件监听*@authorxue......
  • day20 闭包和promise
    闭包(Closure)概述:闭包就是函数嵌套函数,内部函数可以引用外部函数的变量和参数,并且不会被垃圾回收机制所回收.这种结构就称为闭包.函数的生命周期func......
  • day20闭包和promise
    闭包概述:在函数内返回一个函数(函数嵌套函数),内部函数有外部函数的引用。函数的生命周期函数的预编译阶段:1.开辟一个内存空间2.将对应的代码放到这个内存空间函数的执......
  • 代码随想录day20
    654.最大二叉树解题步骤:1、确定递归函数的参数和返回值TreeNode* constructMaximumBinaryTree(vector<int>& nums)2、确定终止条件1TreeNode*node=newTreeN......
  • Day20
    集合Collection1.List和Set集合集合添加的方法add(Objectobj)->往集合中添加一个元素add(intindex,Objectobj)->往集合的指定位置添加一个元素addAll(Collection......
  • day20 700,617,98, 645
    700.二叉搜索树中的搜索classSolution{publicTreeNodesearchBST(TreeNoderoot,intval){if(root.val==val||root==null)returnroot;//1:终止......
  • 代码随想录day20 | 654. 最大二叉树 617. 合并二叉树 700. 二叉搜索树中的搜索 98. 验
    654.最大二叉树题目|文章方法:模拟思路按照题目要求顺序使用递归函数traversal(nums,begin,end)对数组nums二叉树进行模拟。这道题的思路方法与105.从前序遍历和中序......