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;}
};*/
双指针问题告一小段落,前面还有几题写了但是没有记录,懒得再整理了力扣上留有痕迹