首页 > 其他分享 >day10

day10

时间:2022-11-04 22:14:03浏览次数:45  
标签:slow ListNode nullptr fast next while day10

[面试题02.07.链表相交]

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        ListNode *curA = headA;
        ListNode *curB = headB;
        int countA = 0;
        int countB = 0;
        if(curA == nullptr || curB == nullptr)
            return nullptr;
        while(curA->next != nullptr){
            curA = curA->next;
            countA++;
        }
        while(curB->next != nullptr){
            curB = curB->next;
            countB++;
        }
        curA = headA;
        curB = headB;
        while(countA -countB >0){
            curA = curA->next;
            countA--;

        }
        while(countB - countA >0){
            curB = curB->next;
            countB--;
        }
        while(curA != nullptr){
            if(curA == curB)
                return curA;
            curA = curA->next;
            curB = curB->next;
        } 
        return nullptr;
    }
};
  • 其实我本来没有思路的 而且也错会了题意——题目要求返回相交结点的指针 是要求指向这两个节点的指针地址相同 并不是要求这两个节点内存储的val相同。
  • 看了卡哥思路,我就想着——先把两个链表各自遍历一遍得到各自节点个数——然后把结点个数多的那条链表当前指针向后移 直到该长链表从当前指针所指位置到最后一个结点之间的节点总个数与那条短的相等——接着就是两条链表的当前指针一起往后移,只要当前指针所指向的位置不相同 也就是这两个指针不相等的话 那就一起向后移。
  • 我其实运行了一遍后 有一个错误 就是因为我没考虑如果一开始所给的链表其一或两者都是空链的情况要返回nullptr 只考虑到了两者一起往后移但没有交点要返回nullptr
  • 去看看卡哥写的过程 应该比我这个更简洁吧
while(countA -countB >0){
            curA = curA->next;
            countA--;

        }
        while(countB - countA >0){
            curB = curB->next;
            countB--;
        }  
// 让curA为最长链表的头,lenA为其长度
        if (lenB > lenA) {
            swap (lenA, lenB);
            swap (curA, curB);
        }
        // 求长度差
        int gap = lenA - lenB;
        // 让curA和curB在同一起点上(末尾位置对齐)
        while (gap--) {
            curA = curA->next;
        }
  • 上述代码前者是我写的 后者是卡哥写的 该段代码目的是为了移动较长链表的当前指针 直至两条链表当前指针所指结点到最后一个节点这段长度相等。
  • 面对两个变量大小不确定的情况下要进行相见操作 我的方法是分两种情况 对应两个while 卡哥思路是 利用swap函数保证A>B 那么两者之差就是A-B while(差--){} 即可

[0142.环形链表II]

/**
 * 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) {
        ListNode *fast = head;
        ListNode *slow = head;
        while (slow != nullptr){
            while(fast != nullptr){
                if(fast->next == slow->next)
                    return slow->next;
                fast = fast->next;
            }
            slow = slow->next;
            fast = slow;
        }
        return nullptr;
    }
};
  • 上述只能通过个别案例 不能通过循环入口是下标为0的第一个结点的情况
/**
 * 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) {
        ListNode *fast = head;
        ListNode *slow = head;
        while (slow != nullptr){
            while(fast != nullptr){
                if(fast->next == slow)
                    return slow;
                fast = fast->next;
            }
            slow = slow->next;
            fast = slow;
        }
        return nullptr;
    }
};
  • 改了之后 超出时间限制

  • 还是看看卡哥思路吧

/**
 * 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) {
        ListNode *fast = head;
        ListNode *slow = head;
        while (slow != nullptr){
            if(fast == slow){
                ListNode *index1 = fast;
                ListNode *index2 = head;
                while(index1 != index2){
                    index1 = index1->next;
                    index2 = index2->next;
                }
                return index1;
            }
            fast = fast->next->next;
            slow = slow->next;
        }
        return nullptr;
    }
};
  • 看了思路后 写得是挺顺畅的 就是结果不对>-<
  • 我知道有两处代码不一样 一处是if判断语句中 还有一处是fast走两步 slow走一步 放在while开头还是结尾
  • 我先改了第二处 第一处没变 结果错误 报错为指向了空指针
/**
 * 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) {
        ListNode *fast = head;
        ListNode *slow = head;
        while (fast != nullptr){
            fast = fast->next->next;
            slow = slow->next;
            if(fast == slow){
                ListNode *index1 = fast;
                ListNode *index2 = head;
                while(index1 != index2){
                    index1 = index1->next;
                    index2 = index2->next;
                }
                return index1;
            }
        }
        return nullptr;
    }
};
  • 只改第一处 不改第二处 结果跟之前两处都不改一样 能运行 但是是错误的结果
/**
 * 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) {
        ListNode *fast = head;
        ListNode *slow = head;
        while (fast != NULL && fast->next != NULL){
            fast = fast->next->next;
            slow = slow->next;
            if(fast == slow){
                ListNode *index1 = fast;
                ListNode *index2 = head;
                while(index1 != index2){
                    index1 = index1->next;
                    index2 = index2->next;
                }
                return index1;
            }
        }
        return nullptr;
    }
};
  • 正确答案就是卡哥那样写法 见上
  • 哦 因为fast一次走两步 所以要求fast != nullptr && fast->next != nullptr;这样 fast才能取fast->next->next;
  • 至于为什么fast = fast->next->next; slow = slow->next;这两句要放在while循环的开头而不是结尾 那是因为这俩快慢指针要一开始就得走哇 你放while循环的结尾也行 但只有在while中包含的其他语句并不会受到这俩变量值的影响就可以 。 而本题r如果放在循环的结尾而不是开头 那么if判断语句符合 俩指针岂不是一开始就进去了 那就直接执行return index1语句了 且此时index1并没有进入if循环下的那个whille 循环 值仍是head头结点 所以怎么样 结果都不会变的

明天继续:)

标签:slow,ListNode,nullptr,fast,next,while,day10
From: https://www.cnblogs.com/deservee/p/16859253.html

相关文章

  • 代码随想录Day10
    LeetCode459重复字符串给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母,并且长度不超过10000。示例1:输入:"abab"输......
  • 【算法训练营day10】理论基础 LeetCode232. 用栈实现队列 LeetCode225. 用队列实现栈
    【算法训练营day10】理论基础LeetCode232.用栈实现队列LeetCode225.用队列实现栈理论基础栈常用函数#include<stack>stack<int>s;s.empty();//如果栈为......
  • day10-习题
    习题1.Homework01(1) D--没有在别名上加引号(ps:别名的as可以省略)(2) B--判断null或非空不能用不等于号(3) C2.Homework02写出查看dept表和emp表的结构的sql......
  • 进入python的世界_day10_python基础——函数之参数、名称空间
    一、位置参数位置形参​ 函数定义阶段(函数定义第一行)括号内从左往右,依次填写变量名位置实参​ 函数调用阶段括号内从左往右,依次填写传入的数据值"""1.位置形参......
  • Python学习路程——Day10
    Python学习路程——Day10定义函数''' 函数的使用必须遵循’先定义,后调用’的原则。函数的定义就相当于事先将函数体代码保存起来,然后将内存地址赋值给函数名,函数名就是......
  • Day10函数基础学习以及计算机硬盘修改数据的原理(了解)
    今日内容概要文件内光标的移动实战演练计算机硬盘存取数据的原理文件内容修改函数简介函数的语法结构函数的定义与调用内容详细文件内光标移动案例(了解)im......
  • day10 -方法
    ##方法###方法的重载在一个类中有相同的函数名称,但是形参不同的函数 规则:1.方法名称必须相同2.参数列表必须不同(个数不同,类型不同,参数排列顺序不同)3.返回值类型......
  • day10- 练习(计算器的实现)
    1publicstaticvoidmain(String[]args){2Scannerscanner=newScanner(System.in);3System.out.println("输入:");4intx=s......
  • 代码随想录day10 ● 459.重复的子字符串 ● 字符串总结 ● 双指针回顾
    459.重复的子字符串1classSolution{2public:3boolrepeatedSubstringPattern(strings){4stringt=s+s;5//掐头去尾6......
  • day10
    双指针总结数组移除某一个元素快慢一起向后遍历,遇到要删除的元素。快先走,然后快指针直接覆盖要删除的元素classSolution{publicintremoveElement(int[]n......