您的位置:首页 > 游戏 > 游戏 > leetcode力扣_双指针问题

leetcode力扣_双指针问题

2024/10/5 13:53:01 来源:https://blog.csdn.net/bici_1/article/details/140149626  浏览:    关键词:leetcode力扣_双指针问题

141. 环形链表

思路:判断链表中是否有环是经典的算法问题之一。常见的解决方案有多种,其中最经典、有效的一种方法是使用 快慢指针(Floyd’s Cycle-Finding Algorithm)

  • 初始化两个指针:一个快指针(fast)指向头节点的下一个节点(head->next),一个慢指针(slow)指向头节点(head)。
  • 移动指针
    • 慢指针每次移动一步。
    • 快指针每次移动两步。
  • 判断环的存在
    • 如果链表中存在环,那么快指针和慢指针最终会在环中相遇。
    • 如果链表没有环,快指针会遇到 NULL(链表的末尾)。

解答如下:

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode(int x) : val(x), next(NULL) {}* };*/
class Solution {
public:bool hasCycle(ListNode *head) {//如果头指针为空或者下一个为空即链表只有一个元素//那么这个链表就不是循环的if(head == nullptr  || head->next == nullptr ){return false ;}ListNode* slow = head;ListNode* fast = head->next;//循环停止的条件是slow和fast指向同一个元素//或者 fast或fast->next指向NULLwhile(slow != fast){if(fast == nullptr  || fast->next == nullptr ){return false ;}slow = slow->next ;fast = fast->next->next ;}return true ;}
};

循环条件也可以改为其他的形式,或者使用do-while循环,使用do-while循环,则需要对fast和slow的初值进行更改:

//使用do-while循环
class Solution {
public:bool hasCycle(ListNode *head) {//如果头指针为空或者下一个为空即链表只有一个元素//那么这个链表就不是循环的if(head == nullptr  || head->next == nullptr ){return false ;}ListNode* slow = head;ListNode* fast = head;//循环停止的条件是slow和fast指向同一个元素//或者 fast或fast->next指向NULLdo{if(fast == nullptr || fast->next == nullptr){return false ;}slow = slow->next ;fast = fast->next->next ;}while(slow != fast);return true ;}
};

另外也可以将fast != nullptr && fast->next != nullptr放在外层:

class Solution {
public:bool hasCycle(ListNode *head) {//如果头指针为空或者下一个为空即链表只有一个元素//那么这个链表就不是循环的if(head == nullptr  || head->next == nullptr ){return false ;}ListNode* slow = head;ListNode* fast = head;//循环停止的条件是slow和fast指向同一个元素//或者 fast或fast->next指向NULLwhile(fast != nullptr && fast->next != nullptr){//在循环中应首先移动指针,然后再检查 slow 和 fast 是否相等slow = slow->next ;fast = fast->next->next ;if(slow == fast){return true ;}}return false ;}
};

524. 通过删除字母匹配到字典里最长单词

题目描述:给你一个字符串 s 和一个字符串数组 dictionary ,找出并返回 dictionary 中最长的字符串,该字符串可以通过删除 s 中的某些字符得到。如果答案不止一个,返回长度最长且字母序最小的字符串。如果答案不存在,则返回空字符串。

思路:开始自己想起来有点乱糟糟的,看了一下官方给的思路,然后理了一下。

在写的过程中,while块中的语句些的稍微复杂了一点,看了别人的代码后改了一下,原来是这样写的:完全按照想的逻辑,没有思考简化

while(m<slen){//只要还没将s搜索完就要继续搜索if(s[m] == dictionary[i][d]){d++;m++;} else{m++;}
}

然后就是if块中的代码,写得乱糟糟的也,看了一下别人的代码,茅塞顿开,我写的时候在想,怎么才能顺利的存进去第一个满足要求的字符串,因为最开始没有目标字符串,怎么比较长度呢,后来知道使用默认构造函数 string ans; 定义一个 std::string 对象时,它会被初始化为一个空字符串,长度为0,所以可以这样直接比较。

基础薄弱脑袋空空

正确代码如下:

class Solution {
public:string findLongestWord(string s, vector<string>& dictionary) {int k = dictionary.size();//长度为4int slen = s.length();//长度为8string obj ;for(int i = 0;i<k;i++){//int cnt = 0;//获得每一个元素的长度lenint len = dictionary[i].size();//例如第一个元素为ale,长度就为3//下面判断该元素是不是字符串s的子元素int m=0,d=0;while(m<slen){//只要还没将s搜索完就要继续搜索if(s[m] == dictionary[i][d]){d++;} m++;}//cnt==len说明该字符串在字典中存在if(d == len ){if(len > obj.length()){obj = dictionary[i];//有点奇怪,为什么要加一个dictionary[i] < obj这个条件//原题目中字母序最小的字母序最小的字符串是这个意思嘛//比较相同长度的字符串的大小,输出小的作为最后的结果} else if((len == obj.length()) && dictionary[i] < obj){obj = dictionary[i] ;} else{obj = obj ;}}}return obj;}
};//csdn上的答案
/*class Solution {
public:string findLongestWord(string s, vector<string>& dictionary) {//处理string ans;int n = s.size();//字符串的长度//auto& str : dictionary 是 C++11 引入的范围基 for 循环的一部分//用于遍历容器 dictionary 中的每个元素,并使用 str 作为对每个元素的引用。for (auto& str : dictionary){int m = str.size();//dictionary中元素的长度int i = 0, j = 0;while (i < m && j < n){if (str[i] == s[j]) i++;j++;}//处理if (i == m){if (str.size() > ans.size()){ans = str;}else if (str.size() == ans.size() && str < ans){ans = str;}}}return ans;}
};*/

双指针问题告一小段落,前面还有几题写了但是没有记录,懒得再整理了力扣上留有痕迹

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com