1、数组基础理论
int a[m][n];
数组长度表示:a[0].length
数组宽度表示:a.length
2、704.二分查找
特征:数组是升序的找某个数,那就使用二分法。时间复杂度O(log n),空间复杂度O(1)
我使用左闭右闭区间
计算中点: int mid = l+((r-l)>>1); int mid = l+(l-r)/2;
注意:int mid = (l+r)/2; (量大容易溢出)
class Solution {
public int search(int[] nums, int target) {
//升序=》二分查找
if(nums.length ==0) return -1;
int l=0,r=nums.length-1;
while(l<=r){
int mid = l+((r-l)>>1);
if(target==nums[mid]){
return mid;
}else if(target>nums[mid]){
l = mid+1;
}else{
r =mid-1;
}
}
return -1;
}
}
注意点1:
第一次计算中点:int mid = l+(r-l)>>1;没注意运算符号的优先级。报超出时间复杂度.
应该写为:int mid = l+((r-l)>>1);
注意点2:
这道题写过很多次了,每次判断的时候我都写成:if(target==mid)
,结果运行就不对,我是一个马大哈。
应该写为:if(target==nums[mid])
,比较的是数组里面的值。
3、27.移除元素
暴力法,找到目标值,然后后面的数全部往前移动一位,数组大小减一
时间复杂度:O(n^2) ,空间复杂度:O(1)
class Solution {
public int removeElement(int[] nums, int val) {
//暴力法,找到后后面的向前移动
if(nums.length ==0) return 0;
int size = nums.length;
for(int i =0;i<size;i++){
if(val == nums[i]){ // 发现需要移除的元素,就将数组集体向前移动一位
for(int j=i+1;j<size;j++){
nums[j-1] = nums[j];
}
i--; //因为所有的值都向前移动了一位,所以i也需要向前移动一位
size--; //此时数组大小减1
}
}
return size;
}
}
双指针法,用一个for代替两个for,时间复杂度为O(n)
定义快慢指针
快指针:寻找新数组的元素 ,新数组就是不含有目标元素的数组
慢指针:指向更新 新数组下标的位置
public int removeElement(int[] nums, int val) {
//双指针法,定义快慢指针
int slowIndex =0;
for(int fastIndex = 0;fastIndex<nums.length;fastIndex++){
if(nums[fastIndex]!=val){ //值不等时,慢指针+1
nums[slowIndex] = nums[fastIndex];
slowIndex++;
}
//值相等时,慢指针不动,快指针多走,等遇到不等时,慢指针指向的值被快指针指向的值覆盖
}
return slowIndex;
}