目录
数组理论基础
代码随想录学习链接:数组理论基础
leetcode704.二分查找
题目链接:704.二分查找
思路
每次更新缩小一半判断区间,直到区间的中间元素为寻找的目标值。需要注意while判断条件是left <=right 还是 left < right. 涉及到判断区间是[left,right]左闭右闭还是[left,right)左闭右开。
while(left <= right)
{
...
if(target < middle)
right = middle -1;//left == right在区间[left,right]有意义
...
}
while(left < right)
{
...
if(target < middle)
right = middle;//left == right在区间[left,right)无意义
...
}
使用二分查找的前提:
1.有序数组
2.无重复元素(返回结果下标可能不唯一)
代码
左闭右闭
class Solution {
public:
int search(vector<int>& nums, int target) {
int N = nums.size();
int left = 0;
int right = N - 1;
int middle;
while (left <= right)
{
middle = left + (right - left) / 2;
if(target < nums[middle])
right = middle -1;
else if(target > nums[middle])
left = middle +1;
else return middle;
}
return -1;
}
};
左闭右开
class Solution {
public:
int search(vector<int>& nums, int target) {
int N = nums.size();
int left = 0;
int right = N ;
int middle;
while (left < right)
{
middle = left + (right - left) / 2;
if(target < nums[middle])
right = middle;
else if(target > nums[middle])
left = middle +1;
else return middle;
}
return -1;
}
};
复杂度
时间复杂度:O(logn) ,判断区间每次更新都缩小一半
空间复杂度:O(1) ,给定的有序数组
leetcode27.移除元素
题目链接:27.移除元素
思路
1.暴力解法:
通过双重循环,第一层判断是否为移除元素,第二层循环从该元素的后一位元素开始,一个一个往前覆盖。
2.双指针:
通过双指针从而在一重循环中完成双重循环的任务
——若快指针当前指向的值不为移除元素,则快指针指向的元素覆盖给慢指针指向的元素,双指针向后挪动。
——若快指针当前指向的值为移除元素,则快指针向后挪动、慢指针不动,直到快指针挪动后指向非移除元素时,覆盖给慢指针指向元素。
代码
暴力解法
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int size = nums.size();
int i,j;
for(i = 0; i < size; i++){
if(nums[i] == val){
for(j = i + 1; j < size; j++){
nums[j-1] = nums[j];
}
i--;//移除元素被覆盖,判断元素往前挪动一位
size--;//搜索到移除元素,size减一
}
}
return size;
}
};
复杂度
时间复杂度:O(n^2) ,双重循环
空间复杂度: O(1) ,给定数组
双指针
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int slowIndex,fastIndex;
slowIndex = 0;
int size = nums.size();
for(fastIndex = 0; fastIndex < size; fastIndex++){
if(nums[fastIndex] != val )
nums[slowIndex++] = nums[fastIndex];
}
return slowIndex;
}
};
复杂度
时间复杂度:O(n) ,一重循环判断双指针挪动策略
空间复杂度 :O(1) ,给定的判断数组