文章目录
双指针处理方法
- 1.快慢指针,对于一个链来说,即要知道链表的长度还要能够知道列表的中间的位置和元素,同时时间复杂度不能太高
则:一个二倍速指针和一个一倍速指针配合,就能实现上面的要求 同时还方便反转链表,时间复杂度只有O(1/2),效率非常的高
倍速例程:
ListNode *slow=head,*fast=head; //快慢指针(二倍速和一倍速)
for( ; fast&&fast->next ; fast=fast->next->next,slow=slow->next); //快慢指针迭代找中点
反转例程:
ListNode * firstHalf = null;//在向后遍历的同时进行反转
for (int i = 0; i < size / 2; i++) {
ListNode * temp = secondHalf;
secondHalf = secondHalf.next;
temp.next = firstHalf;
firstHalf = temp;
}
- 2.前后指针,对于双指针来说同样有类数组的直接前后指针同时就行,前提是数组需要有序,运行时前后指针联动运行,满足条件前指针向前,不满足条件时,后指针向后运行(或者相反)
//i,k为数组第一个和最后一个下标
//下面数组假设只有小写字母
while(i<=h)
{
if((int(s[i])>=48&&int(s[i])<=57)||( int(s[i])>= 97&&int(s[i])<=122))
{
if((int(s[k])>=48&&int(s[k])<=57) || ( int(s[k])>= 97&&int(s[k])<=122))
{
if(s[i] == s[k])
{
i++;
k--;
}
else
{
return false;
}
}
else
{
k--;
}
}
else
{
i++;
}
}
另外判断字符是不是 数字和字母;isalnum()函数,是-返回非零,否-返回零
将大小写字母统一成一种形式: tolower()函数.
- 3.移动零-思路
任务:把一个数组,数组中非零元素有序排列,把数组中的零元素都放到数组的后面
而数组中非零元素放到数组的前面同时,非零元素保持有序
- 慢指针 记录非零元素(是非零元素就计数),快指针遍历整个数组
- 同时是非零元素就就填充到对应计数的数组位置上
这样做的代码:
void moveZeroes(vector<int>& nums) {
int nozero = 0;
for(int i = 0;i<nums.size();i++)
{
if(nums[i]!=0)
{
nums[nozero] = nums[i];
nozero++;
}
}
for(int i = nozero;i<nums.size();i++)
{
nums[i] = 0;
}
}
时间复杂度 O(n)【遍历一遍数组】,空间复杂度O(1)【只定义了常量】
但是操作了数组中所有的元素
思路二:
1.慢指针。慢指针记录从0开始的 非零元素最后一个零元素的位置(相当于计数)
2.快指针。快指针遍历非零元素交换
时间复杂度和空间复杂度没变但是,程序只对非零元素做了交换,只操作了非零元素
void moveZeroes(vector<int>& nums) {
//这代码太帅了
int nozero = 0;
for(int i=0;i<nums.size();i++)
{
if(nums[i] !=0)
{
swap(nums[nozero],nums[i]);
nozero++;
}
}
}