文章目录
Leetcode142
1.问题描述
2.解决方案
思路
这道题目,不仅考察对链表的操作,而且还需要一些数学运算,主要分以下两个难点步骤
a.判断链表是否有环
双指针!
b.如果有环,如何找到这个环的入口
数学推导,光看代码根本体现不出来,现在已经记住了!
代码实现:
1.while一开始写了个错误版本,还一直没找见bug,原来是一开始fast就是等于slow的,所以根本没进入循环,于是加了判断条件在循环内部
ListNode* slow=head;
ListNode* fast=head;
//while(fast!= nullptr&&fast->next!= nullptr&&slow!=fast){
while(fast!= nullptr&&fast->next!= nullptr){
slow=slow->next;
fast=fast->next->next;
if(fast==slow) break;
}
2.需要注意无环的情况,应该在哪判断呢,应该有两处判断,一个在while里面一个在while结束,其实很好想出来,while里面有访问fast和fast的next,也就是fast->next,fast->next->next,那你自然为了防止段错误就得加上fast!= nullptr&&fast->next!= nullptr,最后while结束判断一下如果不是break出的循环那就是无环!
while(fast!= nullptr&&fast->next!= nullptr){
slow=slow->next;
fast=fast->next->next;
if(fast==slow) break;
}
if(fast== nullptr||fast->next== nullptr) return nullptr;
class Solution {
public:
ListNode* detectCycle(ListNode* head) {
//1.环中相遇
//slow==fast就是相遇节点了
ListNode* slow=head;
ListNode* fast=head;
//while(fast!= nullptr&&fast->next!= nullptr&&slow!=fast){
while(fast!= nullptr&&fast->next!= nullptr){
slow=slow->next;
fast=fast->next->next;
if(fast==slow) break;
}
if(fast== nullptr||fast->next== nullptr) return nullptr;
//2.找到入口节点
//index1从头开始,index2从相遇节点开始,一起往前走
//相遇了就是入口节点
ListNode* index1=head;
ListNode* index2=fast;
while(index1!=index2){
index1=index1->next;
index2=index2->next;
}
return index1;
}
};
Leetcode141
1.问题描述
2.解决方案
比142少一步,只需要判断快慢指针有没有相遇即可
package leetcode;
import common.ListNode;
public class lc141 {
public boolean hasCycle(ListNode head) {
if(head==null) return false;
ListNode slow = head;
ListNode fast = head;
while (slow.next!=null&&fast.next!=null&&fast.next.next!=null){
slow = slow.next;
fast = fast.next.next;
if (slow==fast) return true;
}
return false;
}
}
Leetcode287
1.问题描述
2.解决方案
方法一:先排序,再遍历找相同的数字
public class lc287 {
public int findDuplicate(int[] nums) {
Arrays.sort(nums);
for (int i = 1; i < nums.length; i++) {
if(nums[i]==nums[i-1]) return nums[i];
}
return 0;
}
}
方法二:和141,142找环入口一样的思路
class lc287_1 {
public int findDuplicate(int[] nums) {
int slow = 0;
int fast = 0;
while (slow<nums.length&&fast<nums.length&&nums[fast]<nums.length) {
slow = nums[slow];
fast = nums[nums[fast]];
if (slow==fast) {
int t1 = slow;
int t2 = 0;
while (t1!=t2) {
t1 = nums[t1];
t2 = nums[t2];
}
return t1;
}
}
return -1;
}
}