3. 在排序数组中查找元素的第一个和最后一个位置(34)
C++:
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
int left = 0;
int right = nums.size() - 1;
int start = -1, end = -1;
while (left <= right){
int middle = (left + right) / 2;
if (nums[middle] < target){
left = middle + 1;
}
else if (nums[middle] > target){
right = middle - 1;
}
else{
start = middle;
end = middle;
break;
}
}
if (start == -1){
return {start, end};
}
else{
while (nums[start] == target){
if (start - 1 == -1){
start -= 1;
break;
}else{
start -= 1;
}
}
while (nums[end] == target){
if (end + 1 == nums.size()){
end += 1;
break;
}else{
end += 1;
}
}
return {start + 1, end - 1};
}
}
};
写的没啥毛病,就是太慢了
存在一个问题,最开始写的代码中,return [start,end];
会出现错误:
- 在
return
语句中,你尝试返回一个匿名数组,但是 C++ 中并不支持这种语法。如果你想返回一个包含start
和end
的向量,应该声明一个vector<int>
类型的变量,并将start
和end
添加到该向量中,然后返回该向量。 - 在
return
语句的后续部分中,你试图返回[start + 1, end - 1]
,这是错误的语法。应该使用vector
类型的变量来存储start + 1
和end - 1
,然后返回这个向量。
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
vector<int> res{-1,-1};
if(nums.empty())return res;
int l=0, r=nums.size()-1;
//find first place
while(l<=r){
int mid = (l+r)>>1;
if(target <= nums[mid]){
r = mid-1;
}else if (target>nums[mid]){
l = mid+1;
}
}
if(l<nums.size()&&nums[l]==target)res[0]=l;
l=0;
r=nums.size()-1;
while(l<=r){
int mid = (l+r)>>1;
if(target < nums[mid]){
r = mid-1;
}else if (target>=nums[mid]){
l = mid+1;
}
}
if(r>=0&&nums[r]==target)res[1]=r;
return res;
}
};
int mid = (l+r)>>1;
:
int mid = (l+r)>>1;
这行代码是用于计算中间值 mid
的,它使用了右移位运算符 >>
来实现除以2的操作,这是一种位运算的快速计算方法。这种方法在对整数进行除法时会将结果向下取整,与使用除法运算符 /
的效果相同,但是速度更快。
在这行代码中,l
和 r
分别表示左边界和右边界的索引值,mid
表示中间索引的值。通过将 l
和 r
的二进制表示向右移动一位,即将其除以2,得到了 mid
的值。
重点关注上述代码的 target 与 nums[mid] 中间的符号(等号不在谁那,谁就是一个准的值)
4. 移除数据(27)
C++:
暴力解法:两层for循环,一层循环遍历数组元素,一层更新数组
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int size = nums.size();
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--;
size--;
}
}
return size;
}
};
i--;
是因为将原来这个位置上的数覆盖了,这个位置变成了一个新的数字,那么就需要后退一位,方便后续i++
之后,还能再次检索到这个位置上的新数字,从而对其进行判断是否需要删除
快慢指针:
快指针用于获取新数组的元素;
慢指针用于获取新数组的下标;
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int size = nums.size();
int slowIndex = 0;
for (int fastIndex = 0; fastIndex < size; fastIndex++){
if (nums[fastIndex] != val){
nums[slowIndex] = nums[fastIndex];
slowIndex++;
}
}
return slowIndex;
}
};
if (nums[fastIndex] != val){}
在寻找到的数组不等于目标值的时候,这个数值才是新数组应该加入的元素