算法第三天 双指针

历经时长:7月12日-7月13日

今日总结:

  1. 画图呀!不能眼高手低
  2. 不要以为双指针就是头尾指针,这次的是两个指针从左至右的快慢指针
  3. 双指针=>想想二分
  4. 返回vector可以返回 {1, 2},不用创建对象
  5. 想清楚逻辑关系

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};
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容