2023/8/9日 力扣刷题
双指针
class Solution {
public int removeElement(int[] nums, int val) {
//双指针法,类似于开辟新数组,但是将本数组看成新数组。
//一根指针用于遍历,另外一根用于更新。
//当!=val的时候更新
int j=0;
for(int i=0;i<nums.length;i++){
if(nums[i]!=val){
nums[j++]=nums[i];
}
}
return j;
}
}
总结
双指针法删除数组的数据,这是一个经典题,其要求不能开辟新的数组而是原地删除。
其实本质上这个题的思路和开辟新数组是一样的,只是这个新数组在原地罢了。
使用i指针来进行遍历,j指针进行更新,通过遇到不等于val的数据就更新,遇到等于val的就跳过。
实质上在原数组上创建了一个新的数组,将原数组的不为val的元素按顺序更新到了“新数组”上。
二分查找
闭区间
class Solution {
public int search(int[] nums, int target) {
//二分查找
int left=0;
int right=nums.length-1;
while(left<=right){
int mid=(left+right)/2;
if(nums[mid]>target){
right=mid-1;
}else if(nums[mid]<target){
left=mid+1;
}else if(nums[mid]==target){
return mid;
}
}
return -1;
}
}
左闭右开
class Solution {
public int search(int[] nums, int target) {
//二分查找
//左闭右开
int left=0;
int right=nums.length;
while(left<right){
int mid=(left+right)/2;
if(nums[mid]>target){
right=mid;
}else if(nums[mid]<target){
left=mid+1;
}else if(nums[mid]==target){
return mid;
}
}
return -1;
}
}
总结
二分查找其需要数组呈现递增(或者递减)。利用递增数组的规律性,使得本来暴力遍历数组找数据的O(n)的时间复杂度降低到了O(log2n)。即每次只找一半的数组。
其中本身所需要注意的是:
1.区间问题,即指针所指的数是否在数组内。若采用闭区间,即指针所指的数在数组内,则每次移动left 或者 right指针时 mid指针是不在区间内的,所以left=mid+1;right=mid-1; 且当left指针和right指针重叠时,该数是在区间内的,所以要加一次判断。而采用左闭右开的形式下,right指针就不需要mid-1了,而是直接等于mid。且当left==right时区间内没有数了,则不需要再加一次判断。
2.我自身的问题,因为很久没写代码了,所以在写left=mid+1; right=mid-1;时写了自增符号,导致代码出现问题,通过debug恍然大悟,后边写自增符号是先赋值后自增。