一、环形链表
- 首先怎么判断一个链表有环?即使用双指针法slow,fast,将slow和fast先指向链表的起始位置,再将slow每次移动一个位置,fast每次移动两个位置,这样如果链表有环,slow指针和fast指针必定能在环内相遇。
- 注:如果链表只有一个节点和两个节点怎么办?即while循环条件为fast&&fast->next存在。
- return语句用于结束当前正在执行的函数,因此在while循环中如果slow指针和fast指针相遇即return true,否则要等到while循环结束后没有找到环return false。
class Solution{
public:
bool hasCycle(ListNode *head){
ListNode *slow=head;
ListNode *fast=head;
while(fast&&fast->next){
slow=slow->next;
fast=fast->next->next;
if(slow==fast){
return true;
}
}
return false;
}
};
二、环形链表II
环形链表II
- 在确定有环的情况下如何判断环的入口,用公式计算下
- 首先当slow与fast相遇时slow走了x+y,fast走了x+y+n(y+z),x为head到环入口的距离,y为环入口到相遇位置的距离,z为环内相遇位置到环入口的距离。
- 在相同时间内slow每次只移动一个位置,而fast每次移动两个位置,因此相遇时可列等式
2(x+y)=x+y+n(y+z),化简可得x=(n-1)(y+z)+z.,有两种情况:n=1即fast跑了一圈相遇,n>1即fast跑了n圈相遇即最终x=z即可。 - 设置两个index:index1代表head位置,index2代表fast,index1和index2每次移动一个位置,相等时即为环的入口,返回index1或者index2.
![在这里插入图片描述](https://img-blog.csdnimg.cn/fff55c1b4b3949d1b026c793a5e6de58.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5rGf5Y2X5rGq,size_20,color_FFFFFF,t_70,g_se,x_16)
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode *slow=head;
ListNode *fast=head;
while(fast&&fast->next){
slow=slow->next;
fast=fast->next->next;
if(slow==fast){
ListNode *index1=head;
ListNode *index2=fast;
while(index1!=index2){
index1=index1->next;
index2=index2->next;
}
return index1;
}
}
return NULL;
}
};
三、有序数组的平方
977. 有序数组的平方
- 这题有暴力法和双指针法,暴力法时间复杂度O(N+log(N)),暴力法无非就是先平方,再sort排序。
- 数组其实是有序的,只不过平方后负数可能会变大,平方的最大值就在数组的两端,不是在左边就是在右边,因此使用双指针指向数组两端。
注:for循环初始化时int i=0,j=k;初始化多个值时用逗号隔开,i++,j–可在循环内部写出,不一定要在括号内写,但末尾的分号不能丢。
for(int i=0,j=k;i<=j;)
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
vector<int>result(nums.size());
int k=nums.size()-1;
for(int i=0,j=k;i<=j;)
{
if(nums[i]*nums[i]<=nums[j]*nums[j]){
result[k]=nums[j]*nums[j];
k--;
j--;
}
else{
result[k]=nums[i]*nums[i];
k--;
i++;
}
}
return result;
}
};