代码均为伪代码!!!!!!
数组
一、二分法
1.明确区间(左闭右闭、左闭右开)
2.左闭右闭
left = 0;
right = numsize-1;
while (left <= right){ ///看区间是否合法,当左闭右闭时,left可以等于right
middle = (left-right)/2;
if(num[middle] > taget)
right = middle - 1; //middle一定不是target,又因为是左闭右闭区间,所以新区间不包含middle,因此right=middle-1
else if (num[middle]<target)
left = middle + 1;
else return middle;
}
return -1;
3.左闭右开
left = 0;
right = numsize;
while (left < right){ ///同上,看区间是否合法,当左闭右开时,left就不能等于right了
middle = (left-right)/2;
if(num[middle] > target)
right = middle; ///因为是右开,无法取到右边界,所以不能是middle-1
else if(num[middle] < target)
left = middle+1;
else return middle;
}
return -1;
二、移除元素
双指针算法
定义一个快指针和一个慢指针
新数组下标值为慢指针。
在快指针向前推进时,可以根据需要判断慢指针是否需要跟进,以此滤去不需要的元素
num = [1,2,3,4,5]
slow = 0;
for(fast = 0;fast < numsize;fast++){
If(nums[fast] != val){ //当快指针指到需要删除的元素时,慢指针不动,快指针加一,实现覆盖
num[slow]=num[fast];
slow++;
}
}
return slow; //慢指针即为新数组的大小
有序数组的平方(两个指针向中间聚集)
若想将平方后的数据从小到大排序,说明最大值一定在左边界或右边界,因此从两边向中间推进,以此排序。
vector<int> result
k = numsize-1;
for(i = 0,j = numsize-1; i<=j; )//for循环第三部分可以空着,因为需要判断两个哪个大一点在做i++或j--的行动;小于等于是因为i和j相遇时,相遇的这个数也应该判断。
if(nums[i]*nums[i] > nums[i]*nums[i] ){
result[k] = nums[i]*nums[i];
k--;
I++;
}
else{
result[k--] = nums[j]*nums[j];
j--;
}
return result;
三、滑动窗口
在一个数组中找到和大于等于s的最小长度,返回长度
双指针法
快指针再向前推进时,一旦走过的数之和大于等于目标s了,慢指针开始从前往后缩短窗口,直到窗口内的数小于目标,就可以获得快指针所在位置的最小窗口,快指针便可以继续推进。
i = 0;
result = nums.size;
for(j = 0; j <= nums.size; j++){ //j为末位
sum += nums[j];
while(sum >= s){ //一旦sum符合情况,开始从头往里缩,直到不满足为止
subL = j-i+1;
result = min(result,subL);
sum = sum-nums[i];
i++;
}
}
return result;
四、螺旋矩阵
为防止重复,因使用同一个规则来录入数据,例如左开右闭
startx = 0;
starty = 0;
offset = 1;
count = 1
while (n/2){
for(j = starty; j < n-offset; j++ ){
nums[startx][j] = count++;
}
for(i = startx; i < n-offset; i++ ){
nums[i][j] = count++;
}
for(; j > starty; j--)
nums[i][j] = count++;
for(; i > startx; i--){
nums[i][j] = count++
}
startx++;
starty++;
offset++;
}
if(n%2) nums[i][j] = count++;
return nums;