代码随想录:数组
二分查找
二分查找是对数组中的区间进行查找。
有两种写法:一种是在闭区间内进行查找,另一种是在左闭右开区间内进行查找。
每次查找的时候只有按照这个方法就不会出错。
二分查找
写法一:
class Solution {
public:
int search(vector<int>& nums, int target) {
int left=0,right=nums.size()-1;
int mid;
while(left<=right){
mid = (left+right)/2; //也可以写成
int x=nums[mid];
if(x==target)return mid;
if(x>target){
right=mid-1;
}else{
left=mid+1;
}
}
return -1;
}
};
移除元素
题目链接
方法一:双指针
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int l=0;
for(int i=0;i<nums.size();++i){
if(nums[i]!=val){
nums[l] = nums[i];
l++;
}
}
return l;
}
};
时间复杂度O(n),空间复杂度O(1)
有序数组的平方
题目
方法一:直接把结果排序,时间复杂度O(n + nlog(n)),因为排序最低是nlogn
方法二:双指针。原数组的绝对值可以看作是非递增-非递减的,因此可以从两端进行遍历
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
vector<int> res(nums.size());
int left=0,right=nums.size()-1;
int index = nums.size()-1;
while(left <= right){
if(abs(nums[left])<abs(nums[right])){
res[index] = nums[right] * nums[right];
right -- ;
}else{
res[index] = nums[left] * nums[left];
left ++ ;
}
index --;
}
return res;
}
};
长度最小的子数组
题目描述
方法一:也是用双指针的方法。答案中说是滑动窗口。时间复杂度O(n)
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int sum=0;
int res=1e6;
int left=0,right=0;
for(right=0;right<nums.size();right++){
sum += nums[right];
while(sum>=target&&left<=right){
res = min(res, right-left+1);
sum-=nums[left];
left++;
}
}
if(res == 1e6)return 0;
return res;
}
};
方法二:前缀和 + 二分查找
后面在补
螺旋矩阵II
模拟题。主要是使用循环不变量。
题目
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>>res(n, vector<int>(n));
int startx=0,starty=0;
int loop=n/2;
int i=0,j=0;
int num = 1;
while(loop--){
i=startx;
j=starty;
for(;j<n-starty-1;++j){
res[i][j] = num++;
}
for(;i<n-startx-1;++i){
res[i][j] = num++;
}
for(;j>starty;--j){
res[i][j] = num++;
}
for(;i>startx;--i){
res[i][j] = num++;
}
startx++;
starty++;
}
if(n%2==1){
res[n/2][n/2] = n*n;
}
return res;
}
};
未完待续