数组
数组是存放在连续内存空间上的相同类型数据的集合。
- 数组下标都是从0开始的。
- 数组内存空间的地址是连续的
704. 二分查找
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
数组为有序数组,且数组中无重复元素(一旦有重复元素,使用二分查找法返回的元素下标可能不唯一)
写二分法,区间的定义一般为两种,左闭右闭即[left, right],或者左闭右开即[left, right)
[left, right]
- while (left <= right) ,因为 left == right有意义 [1,1]合法
- if (nums[middle] > target) right 要赋值为 middle - 1,因为当前这个nums[middle]一定不是target,那么接下来要查找的左区间结束下标位置就是 middle - 1
- 时间复杂度:O(log n)
- 空间复杂度:O(1)
int search(int* nums, int numsSize, int target){
int left = 0;
int right = numsSize-1;
int middle = 0;
while(left<=right) {
middle = (left+right)/2;
if(nums[middle] > target) {
right = middle-1;
}
else if(nums[middle] < target) {
left = middle+1;
}
else if(nums[middle] == target){
return middle;
}
}
return -1;
}
[left, right)
- while (left < right),left == right在区间[left, right)无意义 [1,1)不合法
- if (nums[middle] > target) right 更新为 middle,因为当前nums[middle]不等于target,去左区间继续寻找,而寻找区间是左闭右开区间,所以right更新为middle,即:下一个查询区间不会去比较nums[middle]
- 时间复杂度:O(log n)
- 空间复杂度:O(1)
int search(int* nums, int numsSize, int target){
int left = 0;
int right = numsSize;
int middle = 0;
while(left < right){
int middle = (left + right) / 2;
if(nums[middle] > target){
right = middle ;
}else if(nums[middle] < target){
left = middle + 1;
}else{
return middle;
}
} return -1;
}
27. 移除元素
给定一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
暴力解法
两层for循环,一个for循环遍历数组元素 ,第二个for循环更新数组
- 时间复杂度:O(n^2)
- 空间复杂度:O(1)
int removeElement(int* nums, int numsSize, int val) {
int size = numsSize;
for (int i = 0; i < size; i++) {
if (nums[i] == val) { // 发现需要移除的元素,就将数组集体向前移动一位
for (int j = i + 1; j < size; j++) {
nums[j - 1] = nums[j];
}
i--; // 因为下标i以后的数值都向前移动了一位,所以i也向前移动一位
size--; // 此时数组的大小-1
}
}
return size;
}
双指针法
双指针法(快慢指针法): 通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。
- 快指针:寻找新数组的元素 ,新数组就是不含有目标元素的数组
- 慢指针:指向更新 新数组下标的位置
- 时间复杂度:O(n)
- 空间复杂度:O(1)
int removeElement(int* nums, int numsSize, int val){
int slow = 0;
for(int fast = 0; fast < numsSize; fast++) {
//若快指针位置的元素不等于要删除的元素
if(nums[fast] != val) {
//将其挪到慢指针指向的位置,慢指针+1
nums[slow++] = nums[fast];
}
}
//最后慢指针的大小就是新的数组的大小
return slow;
}