数组理论基础——文章链接:代码随想录
题目链接:. - 力扣(LeetCode)
文章讲解:代码随想录
题目一:力扣704——二分查找
给定一个 n
个元素有序的(升序)整型数组 nums
和一个目标值 target
,写一个函数搜索 nums
中的 target
,如果目标值存在返回下标,否则返回 -1
。
示例1:
输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4
示例2:
输入: nums = [-1,0,3,5,9,12], target = 2
输出: -1
解释: 2 不存在 nums 中因此返回 -1
思路:
满足这两个条件可以考虑二分查找法:1.nums数组为有序数组;2.数组中无重复元素。说明使用二分查找法返回的元素下标是唯一的。
我使用的区间是左闭右闭的,一开始我将循环条件设置为while(left < right)
,但是后来发现不对,少了一种情况:
此时,left == right,如果是while(left < right),不满足循环条件,停止查找,就不会找到3,不符要求。
于是改成while(left <= right)
区间的定义就是不变量。要在二分查找的过程中,保持不变量,就是在while寻找中每一次边界的处理都要坚持根据区间的定义来操作,这就是循环不变量规则。
代码:
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0;
int right = nums.size()-1;
int middle = 0;
while(left<=right){
//middle = (left+right)/2;
//int middle = left + ((right - left) / 2);// 防止溢出 等同于(left + right)/2
int middle = left + ((right - left) >> 1);//右移一位相当于除以2
if(nums[middle]>target){//去左边找
right = middle-1;
}else if(nums[middle]<target){//去右边找
left = middle +1;
}else{
return middle;
}
}
return -1;
}
};
关于溢出:使用乘法计算中间索引可以避免除法的截断错误,但需要注意溢出问题。位运算和分步计算可以很好地防止溢出。
vector<int>& nums的一些用法
创建一维vector
vector<int> nums; //不指定长度
vector<int> nums(n); //指定长度
添加元素
nums.push_back(1); //直接在末端添加元素1
删除元素
nums.resize(num.size-i); //删除后面i个元素
nums.pop_back(); //删除最后一个元素
获取长度
nums.size();
判空
nums.empty();
nums.size()==0;
相关题目推荐
题目二:力扣27——移除元素
给你一个数组 nums
和一个值 val
,你需要原地移除所有数值等于 val
的元素。元素的顺序可能发生改变。然后返回 nums
中与 val
不同的元素的数量。
假设 nums
中不等于 val
的元素数量为 k
,要通过此题,您需要执行以下操作:
- 更改
nums
数组,使nums
的前k
个元素包含不等于val
的元素。nums
的其余元素和nums
的大小并不重要。 - 返回
k
。
我的思路:循环扫描数组,遇到第i个val就用数组后面的第i个不是val的值覆盖,同时数组size-1。循环结束,只需要用新的数组size来resize一下数组就好。
我的代码(当数组为空的时候,执行错误,确实是有错误):
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int len=nums.size();
int f2=nums.size()-1,f1=nums[f2];
for(int i=0;i<=nums.size()-1;i++){
if(nums[i]==val){
while(f1==val){
f2--;
f1=nums[f2];
}
nums[i]=f1;
f2--;
f1=nums[f2];
len--;
}
}
nums.resize(len); //删除后面元素
return len;
}
};
双指针思路:设置快慢指针,快指针来寻找新数组需要的元素,赋给慢指针,慢指针来存储新数组需要的元素。
双指针代码:
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];
}
}
return slow;
}
};
相关题目推荐
引用博客: