代码随想录刷题第一天--数组专题
1.二分查找
对于二分查找来说,比较用于出错的地方在于要注意循环变量的不变性;具体来说就是在对于区间进行比较时采用左闭右闭的形式来写:eg[left,right]链接: [link](https://leetcode.cn/problems/binary-search/)
class Solution {
public:
int search(vector<int>& nums, int target) {
int len = nums.size();
int i=0;
int j=len-1;
while(i<=j){
int mid = (i+j)/2;
if(nums[mid]==target){
return mid;
}
else if (nums[mid]<target){
i=mid+1;
}
else{
j=mid-1;
}
}
return -1;
}
};
这里注意的是while(i<=j),由于采用的左闭右闭的形式,所以i==j的情况下也是有效的,也需要进行循环。
2.移除元素
本题的话主要就是需要利用到**双指针法** 一个快指针和一个慢指针,快指针主要用于遍历整个数组,而慢指针主要用于指向元素应该存放的实际位置,这样便可以使用O(n}算法实现移除所有值为target的元素。class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int len1=nums.size();
int sum=0;
for(int i=0;i<len1;i++){
if(nums[i]==val){
sum++;
}
}
int len2 = len1-sum;
int oldIndex = 0;
int newIndex = 0;
while(oldIndex<len1){
if(nums[oldIndex]!=val){
nums[newIndex]=nums[oldIndex];
newIndex++;
}
oldIndex++;
}
return newIndex;
}
};
3.有序数组的平方
这个题主要是一个递增数组的平方的最大值一定是在两边的,由于正数和负数的存在将该数组分为两个有序的部分,然后这样就可以利用**双指针法**去完成两个有序数组的合并,这样便可以使用O(n)实现该题目。 链接: [link](https://leetcode.cn/problems/squares-of-a-sorted-array/)class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int len = nums.size();
vector<int>result;
int i=0;
int j = len-1;
while(i<=j)
{
if(nums[i]*nums[i]>nums[j]*nums[j])
{
result.push_back(nums[j]*nums[j]);
j--;
}
else
{
result.push_back(nums[i]*nums[i]);
i++;
}
}
return result;
}
};
4.最小长度的子数组
链接: [link](https://leetcode.cn/problems/minimum-size-subarray-sum/) 本题的关键思路在于使用滑动窗口,不用两层循环的暴力解法。首先考虑暴力解法其实就是在对滑动窗口的起始位置和终止位置进行遍历枚举,i,j分别对应起始和终止位置,所以有两层循环。所以我们可以考虑使用一层循环实现遍历。
一层循环遍历滑动窗口的终止位置,对应的起始位置通过满足条件后的调整就可 具体代码:
int sum=0;
int i=0;
int j=0;
int subLength=0;
int result= maxn; //INF
for(j<nums.size();j++){ //遍历终止位置
sum+=nums[j];
while(sum>=target) //当前滑动窗口满足条件
{
subLength=j-i+1; //满足条件的子数组长度
result = result<subLength?result:subLength;
sum-=num[i];
i++ //起始位置移动
}
}
cout<<result<<endl; //得到满足条件的最小长度的滑动窗口大小
通过这种方式实现即可利用O(n)实现完成该题目。