「代码随想录算法训练营」第一天(补) | 数组 part1

704. 二分查找

题目链接:https://leetcode.cn/problems/binary-search/
题目难度:简单
文章讲解:https://programmercarl.com/0704.二分查找.html
视频讲解: https://www.bilibili.com/video/BV1fA4y1o715
题目状态:通过

个人思路:

就是简单的二分查找思路,判断数组中间的值是否等于目标值,不等于就更新范围。

具体代码:

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int low = 0, high = nums.size() - 1;
        return Binary(nums, low, high, target);
    }
    int Binary(vector<int> &nums, int low, int high, int target) {
        if(low > high) return -1;

        int mid = low + (high - low) / 2;
        if(nums[mid] == target) {
            return mid;
        }
        else if(nums[mid] > target) {
            return Binary(nums, low, mid - 1, target);
        }
        else {
            return Binary(nums, mid + 1, high, target);
        }
    }
};

27. 移除元素

题目链接:https://leetcode.cn/problems/remove-element/
题目难度:简单
文章讲解:https://programmercarl.com/0027.移除元素.html
视频讲解: https://www.bilibili.com/video/BV12A4y1Z7LP
题目状态:通过

个人思路:

一开始要打算直接用erase函数的,但是感觉这应该不是考察的重点,然后就使用了双指针。

  1. 当左边指针i对应的值等于要删除的元素时,将位于右边的指针j的值覆盖到左边指针,并且j++
  2. 当左边指针i对应的值不等于要删除的元素时,i++

具体代码:

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int i = 0, j = nums.size();
        while(i < j) {
            if(nums[i] == val) {
                nums[i] = nums[j - 1];
                j--;
            }
            else {
                i++;
            }
        }
        return j;
    }
};

卡哥思路我还真没想过,使用快慢指针

实现代码:

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int n = nums.size();
        int i = 0;
        for(int j = 0; j < n; ++j) {
            if(val != nums[j]) {
                nums[i] = nums[j];
                i++;
            }
        }
        return i;
    }
};

26. 删除有序数组中的重复项

题目链接:https://leetcode.cn/problems/remove-duplicates-from-sorted-array/
题目难度:简单
题目状态:通过

个人思路:

学习卡哥上题的思路,使用快慢指针

具体代码:

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        int slow = 0;
        for(int fast = 1; fast < nums.size(); ++fast) {
            if(nums[slow] != nums[fast]) {
                slow++;
                nums[slow] = nums[fast];
            }
        }
        return slow + 1;
    }
};

283. 移动零

题目链接:https://leetcode.cn/problems/move-zeroes/
题目难度:简单
题目状态:通过

个人思路:

快慢指针太好用了,一次过。

  1. 使用快指针遍历;
  2. 当慢指针的值为0,且快指针的值不为0时,快慢指针对应的值交换;
  3. 当慢指针的值不为0时,将慢指针移动到下一个。

具体代码:

class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int i = 0;
        for(int j = 0; j < nums.size(); ++j) {
            if(nums[i] == 0 && nums[j] != 0) {
                swap(nums[i], nums[j]);
            }
            if(nums[i] != 0) i++;
        }
    }
};

844. 比较含退格的字符串

题目链接:https://leetcode.cn/problems/backspace-string-compare/
题目难度:简单
题目状态:没有思路,看题解

当我感觉自己会使用双指针的时候,想法破裂了……

力扣官方题解

1. 栈

当判断一个数组中的元素不为#时,将该元素入栈;而该元素为#且栈不为空时,出栈。最终判断两个字符串的栈是否相同。

实现代码如下:

class Solution {
public:
    bool backspaceCompare(string s, string t) {
        return build(s) == build(t);
    }
    string build(string s) {
        string res;
        for(auto i : s) {
            if(i != '#') {
                res.push_back(i);
            }
            else if(!res.empty()) {
                res.pop_back();
            }
        }
        return res;
    }
};

2. 双指针法

先看图解(来自力扣官方):

一个字符是否会被删掉,只取决于该字符后面的退格符,而与该字符前面的退格符无关。因此当我们逆序地遍历字符串,就可以立即确定当前字符是否会被删掉。

具体地,我们定义 skip 表示当前待删除的字符的数量。每次我们遍历到一个字符:

  • 若该字符为退格符,则我们需要多删除一个普通字符,我们让 skip 加 1;

  • 若该字符为普通字符:

    • skip 为 0,则说明当前字符不需要删去;
    • skip 不为 0,则说明当前字符需要删去,我们让 skip 减 1。

这样,我们定义两个指针,分别指向两字符串的末尾。每次我们让两指针逆序地遍历两字符串,直到两字符串能够各自确定一个字符,然后将这两个字符进行比较。重复这一过程直到找到的两个字符不相等,或遍历完字符串为止。

class Solution {
public:
    bool backspaceCompare(string S, string T) {
        int i = S.length() - 1, j = T.length() - 1;
        int skipS = 0, skipT = 0;

        while (i >= 0 || j >= 0) {
            while (i >= 0) {
                if (S[i] == '#') {
                    skipS++, i--;
                } else if (skipS > 0) {
                    skipS--, i--;
                } else {
                    break;
                }
            }
            while (j >= 0) {
                if (T[j] == '#') {
                    skipT++, j--;
                } else if (skipT > 0) {
                    skipT--, j--;
                } else {
                    break;
                }
            }
            if (i >= 0 && j >= 0) {
                if (S[i] != T[j]) {
                    return false;
                }
            } else {
                if (i >= 0 || j >= 0) {
                    return false;
                }
            }
            i--, j--;
        }
        return true;
    }
};

977. 有序数组的平方

题目链接:https://leetcode.cn/problems/squares-of-a-sorted-array/
题目难度:简单
题目状态:之前做过,且已通过

个人思路:

创建一个新数组res,用来存储结果。
使用双指针分别指向有序数组的两端,并创建一个指针指向res的尾部。
判断双指针所指的值的平方哪个更大,并将更大的值存入res

实现代码:

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        int n = nums.size();
        vector<int> res(n);
        int i = 0, j = n - 1, k = n - 1;
        while(i <= j)
        {
            if(nums[i] * nums[i] > nums[j] * nums[j])
            {
                res[k] = nums[i] * nums[i];
                i++;
            }
            else
            {
                res[k] = nums[j] * nums[j];
                j--;
            }
            k--;
        }
        return res;
    }
};
posted @ 2024-07-07 09:15  云雀AC了一整天  阅读(28)  评论(0编辑  收藏  举报