手撕算法岗!!!
一、数组
1.二分法 查找
前提:①有序数组 ②无重复元素
通过两端点,找到中间值,与查找值相比,将中间下标替换为左端点 + 1或右端点 - 1。
∗ ∗ ∗ *** ∗∗∗找中间值:right + left / 2
为了防止溢出 -> (right - left) / 2 + left
!!![left, right]会了,但[left, right) 有点绕。区间问题。 哦!!他的right开其实是人为的。有点懂了。
循环不变量规则: [left, right] -> while(left <= right)
[left, right) -> while(left < right)
2.移除元素
①双循环暴力解法是可以的… 一遍历二更新 时间复杂度O( n 2 n^2 n2)
②更优:双指针之 快慢指针。
----快指针:寻找新数组的元素
----慢指针:指向更新 新数组下标的位置
int slowPointer = 0;
for(int fastPointer = 0; fast != nums.size(); ++fastPointer){
if(nums[fastPointer] != val)
nums[slowPointer++] = nums[fastPointer];
}
快指针一直在跑,只有满足条件时,慢指针才++跑;
③相向双指针,再看。会改变元素相对位置。
3.有序数组的平方
①暴力 先平方后排序(sort 快排) 时间复杂度为O(n + nlogn) !!!这里快排还需要学一下 (c++提供sort(A.begin(), A.end, cmp) cmp要自己写 return a<b 详情看csdn c++收藏夹里的sort文章)
②双指针呀,放到新数组里。因为是有序的,所以找平方后最大的那个数放进去就行了。 !!!初始化vector a(n, 0) n个0的vector。 O(n)
。 !!!初始化vector a(n, 0) n个0的vector。 O(n)