数组理论基础
安利数组理论基础文章:https://programmercarl.com/%E6%95%B0%E7%BB%84%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html
关键要点:
- 数组下标都是从 0 开始的
- 数组内存空间的地址是连续的
- 数组的元素是不能删的,只能覆盖
Leetcode 704-二分查找
相似题目:
35.搜索插入位置
34. 在排序数组中查找元素的第一个和最后一个位置
题目描述:
https://leetcode.cn/problems/binary-search/
解题思路
二分查找法虽然逻辑简单,思路清晰,但很容易在循环条件、+1-1 这种小细节上出现问题。在这道题中,while 循环条件里 left<right 还是 left<=right 会直接影响到后面的处理。具体情况如下:
左闭右闭
- 当区间为左闭右闭时,即 left<=right,代码如下:
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0;
int right = nums.size() - 1;
while (left <= right) {
int middle = (left + right) / 2;
//也可以写成int middle = left + (right - left) / 2,这样的好处是可以防止溢出
if (target < nums[middle]) {
right = middle - 1;//前面已经判断target<middle,因此在下一次循环中不需要将middle纳入考虑中
}
else if (target > nums[middle]) {
left = middle + 1;//同前,无需在下一次循环中考虑middle
}
else {
return middle;
}
}
// 如果在数组中没有找到target值
return -1;
}
};
左闭右开
当区间为左闭右开,即 left < right,代码如下:
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0;
int right = nums.size();//右为开区间
while (left < right) {//左闭右开
int middle = (left + right) / 2;
//也可以写成int middle = left + (right - left) / 2,这样的好处是可以防止溢出
if (target < nums[middle]) {
right = middle;//右面是开区间,区间中本身不包含nums[middle]
}
else if (target > nums[middle]) {
left = middle + 1;//左闭,考虑middle+1
}
else {
return middle;
}
}
// 如果在数组中没有找到target值
return -1;
}
};
Leetcode 27-移除元素
题目描述:
https://leetcode.cn/problems/remove-element/
解题思路:
暴力解法
这道题上来最简单的思路是直接暴力求解,即遍历数组中的每一个元素,如果这个元素的值与目标值相同,则让该元素后面的元素全部向前移动一位,但注意其时间复杂度为 O(n^2),并不是本道题的最优解
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int count = nums.size();
for (int i = 0; i < count; i++) {
if (nums[i] == val) {
for (int j = i + 1; j < count; j++) {
nums[j -1] = nums [j]; //每找到一个目标值,后面的元素向前覆盖1
}
i--;
count--;
}
}
return count;
}
};
双指针解法
移除元素这道题目可以通过双指针的引入简化时间复杂度,双指针的思路为设置一个快指针和一个慢指针,快指针的作用是判断 nums 中的元素是否等于目标值,而慢指针的作用是确定新数组中存放元素的 index
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int slow = 0;
for (int fast = 0; fast < nums.size(); fast++) {
if (nums[fast] != val) {
nums[slow] = nums[fast];//如果fast指针搜索到的元素不是目标值,则将该元素放入新的数组中
slow++;//有新的元素放入新数组中则slow指针+1
}
}
return slow;
}
};