历经时长:7月12日-7月13日
今日总结:
- 画图呀!不能眼高手低
- 不要以为双指针就是头尾指针,这次的是两个指针从左至右的快慢指针
- 双指针=>想想二分
- 返回vector可以返回 {1, 2},不用创建对象
- 想清楚逻辑关系
283. 移动零
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
// 我写的,覆盖(不算是这道题的考点)
// 先遍历第一次,计算0的个数,知道元素移动的最终位置
// 遍历第二次,一一重新赋值,最后的全为0
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int len = nums.size();
int left = 0, right = len - 1;
int zero_nums=0;
for(int i=0; i <= right; ++i){
if(nums[i]==0) zero_nums++;
}
for(int i=0,j=0; i<=right; ++i){
if(j==(len-zero_nums)) break;
if(nums[i]==0) continue;
nums[j++]=nums[i];
}
for(int i=right; i>=len-zero_nums; i--){
nums[i]=0;
}
}
};
//这道题叫交换0
//双指针方法,快慢指针,这是官方解题
void moveZeroes(vector<int>& nums) {
int len = nums.size(), left = 0, right = 0;
while (right<len)
{
if (nums[right])
{
swap(nums[left++], nums[right]);
}
right++;
}
167. 两数之和 II - 输入有序数组
给定一个已按照 升序排列 的整数数组 numbers ,请你从数组中找出两个数满足相加之和等于目标数 target 。
函数应该以长度为 2 的整数数组的形式返回这两个数的下标值。numbers 的下标 从 1 开始计数 ,所以答案数组应当满足 1 <= answer[0] < answer[1] <= numbers.length 。
你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。
在数组中找到两个数,使得它们的和等于目标值,可以首先固定第一个数,然后寻找第二个数,第二个数等于目标值减去第一个数的差。利用数组的有序性质,可以通过二分查找的方法寻找第二个数。为了避免重复寻找,在寻找第二个数时,只在第一个数的右侧寻找。
// 方法一:二分查找
// 先固定一个数,二分查找另一个数
vector<int> twoSum(vector<int>& numbers, int target) {
for(int i=0; i<numbers.size(); ++i){
int low=i+1, high=numbers.size()-1; // 这里要注意!两个指针要指对位置
int tar = target-numbers[i];
int mid;
while(low<=high){ // 注意这里!!结束条件要牢记,<=
mid = (high - low) / 2 + low; // 注意!记得加low
if(numbers[mid]>tar) high=mid-1;
else if(numbers[mid]<tar) low=mid+1;
else return {i+1, mid+1};
}
}
return {-1, 1};
}
// 方法二:双指针
vector<int> twoSum(vector<int>& numbers, int target) {
int left=0, right=numbers.size()-1;
while(left<right){
if(numbers[left]+numbers[right]>target) right--;
else if(numbers[left]+numbers[right]<target) left++;
else return {left+1,right+1};
}
return {-1, 1};
}