今日学习
代码随想录:数组
内容包含了数组的一些基本概念,其中表明数组只能覆盖,不能删除元素,而C++中Vector和数组不是一样的,vector只是一个容器,Java中没有指针的概念,数组的内存位置不连续
代码随想录:二分查找法
包含了两种二分查找区间:左闭右闭和左闭右开,这两种方法的区分在于取到的中间位置对于left和right边界是否还有意义,而循环结束添加则要判断在何时循环该结束,是left<right还是left<=right
代码随想录:移除元素
一般有两种思路,使用暴力方式,另一种就是使用快慢指针的方式
思路
通过元素的有序性以及程序中寻找一个目标值的概念,考虑使用二分法进行查找,而二分法在此处可以有两种写法,左闭右开和左闭右闭的方式。
今日收获
二分查找两种方式代码(704题):
public int search1(int[] nums, int target) {
//进行左闭右开的方式
int left=0;
int right=nums.length;
if(target<nums[0]||target>nums[nums.length-1]) {
return -1;
}
while(left<right){
int mid=left+(right-left)/2;
if(nums[mid]<target){
left=mid+1;
}else if(nums[mid]>target){
right=mid;
}else{
return mid;
}
}
return -1;
}
public int search(int[] nums, int target) {
//进行左闭右闭的方式
int left=0;
int right=nums.length-1;
if(target<nums[0]||target>nums[nums.length-1]) {
return -1;
}
while(left<=right){
int mid=left+(right-left)/2;
if(nums[mid]<target){
left=mid+1;
}else if(nums[mid]>target){
right=mid-1;
}else{
return mid;
}
}
return -1;
}
时间复杂度O(logn) 控件复杂度O(1)
力扣第27题移除元素
该题第一反应就是直接暴力法移除,通过两层循环,第一层循环数组,第二层循环将数据提前一位,注意,随着数据的删除,数组的size会缩减,并且由于数据向前移动,那么第一层的循环要回退一步。
public int removeElement(int[] nums, int val) {
//移除元素时,使用暴力法
int flag=nums.length;
for(int i=0;i<flag;){
if(nums[i]==val){
for(int j=i+1;j<flag;j++){
nums[j-1]=nums[j];
//这里尽量不使用j=i,因为这样就必须限制j的范围
}
flag--;
}
if(nums[i]!=val){
i++;
}
}
return flag;
}
代码的时间复杂度为O(n^2)
该事件复杂度较高,可以使用快慢指针的方式进行优化
public int removeElement(int[] nums, int val) {
//移除元素时,使用快慢指针法
int slow=0;
int fast=0;
int flag=nums.length;
for(int i=0;i<flag;i++){
if(nums[i]!=val){
nums[slow]=nums[fast];
slow++;
fast++;
}else
{
fast++;
}
}
return slow;
}
此处的时间复杂度为O(n),空间复杂度为O(1)