题目概览
1.二分查找:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
2. 移除元素:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
3.有序数组的平方:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
4.长度最小的子数组:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
5.螺旋矩阵2:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
二分查找
根据区间的闭合关系将二分查找分为两个模版
左闭,右闭区间
class Solution {
public int search(int[] nums, int target) {
int l=0;
int r=nums.length-1;
while(l<=r){
int mid=(l+r)/2;
if(nums[mid]>target) //如果查找元素在nums[mid]左半边 右边界发生变化
r=mid-1;
else if(nums[mid]<target)// 如果查找元素在nums[mid]右半边 左边界发生变化
l=mid+1;
else return mid;
}
return -1;
}
}
左闭,右开区间
class Solution {
public int search(int[] nums, int target) {
int l=0;
int r=nums.length;
while(l<r){
int mid=(l+r)/2;
if(nums[mid]>target) r=mid;
else if(nums[mid]<target) l=mid+1;
else return mid;
}
return -1;
}
}
时间复杂度:O(logn)
空间复杂度:O(1)
移除元素
快慢指针的运用
class Solution {
public int removeElement(int[] nums, int val) {
int low=0;//慢指针 用来记录移除指定元素之后数组内的下标
for(int high=0;high<nums.length;high++){ //快指针 用来遍历数组中每一个元素
if(nums[high]!=val){
nums[low]=nums[high];//移除元素
low++;//慢指针右移
}
}
return low;
}
}
时间复杂度:O(n)
空间复杂度:O(1)
有序数组的平方
双指针算法+空间换时间
额外开辟一个数组用来存储非递减顺序的平方值
慢指针从数组左侧开始,快指针从数组右侧开始
两两对比 用额外开辟的数组来记录其中的较小值 直到两指针相遇
class Solution {
public int[] sortedSquares(int[] nums) {
int[] a=new int[nums.length];
int k=nums.length-1;
for(int i=0,j=nums.length-1;i<=j;){
if(nums[i]*nums[i]<=nums[j]*nums[j]){
a[k]=nums[j]*nums[j];
k--;
j--;
}else{
a[k]=nums[i]*nums[i];
k--;
i++;
}
}
return a;
}
}
时间复杂度:O(n)
空间复杂度:O(n)
长度最小的子数组
快慢指针
定义一个变量sum用来记录遍历过程中的数组元素之和 sublength记录当前sum符合要求 再进行比对选出最小值
慢指针用来记录子数组的起始位置 快指针用来遍历数组
当sum满足条件后 记录长度 慢指针向右移动 同时更新sum值 直到不满足条件(体现在代码上这里是while而不是if)
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int sum=0;
int sublength=0;
int i=0;
int res=Integer.MAX_VALUE;//设置最大值 然后更新
for(int j=0;j<nums.length;j++){
sum+=nums[j];
while(sum>=target){
sublength=j-i+1;
res=Math.min(res,sublength);
sum-=nums[i];
i++;
}
}
return res==Integer.MAX_VALUE?0:res;
}
}
时间复杂度:O(n)
空间复杂度:O(1)
螺旋矩阵2
此处并没有使用代码回想录的解法 个人觉得引入变量太多过于复杂
参考acwing中的解法
定义x轴位移变量和y轴位移变量数组 定义一个二维数组存储结果
顺序:x轴位移变量先不变 y轴位移变量递增
x轴位移变量递增 y轴位移变量不变
x轴位移变量不变 y轴位移变量递减
x轴位移变量减小 y轴位移变量不变
如何确定遍历方向的改变?
超出数组边界 小于0 或 大于等于数组长度 或 数组未被访问过
如何保证圈数的循环
定义变量t用来确保循环
t = ( t + 1 ) % 4
class Solution {
public int[][] generateMatrix(int n) {
int[][] res=new int[n][n];
int t=0;
int[] dx={0,1,0,-1};
int[] dy={1,0,-1,0};
for(int i=0,j=0,k=1;k<=n*n;k++){
res[i][j]=k;
int x=i+dx[t],y=j+dy[t];
if(x<0||y<0||x>=n||y>=n||res[x][y]!=0)
t=(t+1)%4;
i+=dx[t];
j+=dy[t];
}
return res;
}
}
时间复杂度:O(n^2)
空间复杂度:O(1)
总结
数组章节最长见解法为双指针(快慢指针)的运用(有待补充)
常见类型:
快慢指针从同一起点出发,快指针用于遍历,慢指针用于更改/存储新的值
双指针从两端出发,同时进行对比 选出符合条件的