Leetcode刷题DAY69

简单题

Leetcode: 9 回文数

简单的想法就是将数字转化为字符进行比较,但是这样占空间

class Solution {
public:
    bool isPalindrome(int x) {
        if(x < 0) return false;
        if(x < 10 && x >= 0) return true;
        vector<int> num;
        while(x > 9){
            num.push_back(x%10);
            x = x/10;
        }
        num.push_back(x);

        int i = 0;
        int j = num.size() - 1;
        while(i <= j){
            if(num[i] == num[j]){
                i++;
                j--;
            }
            else{
                return false;
            }
        }
        return true;

    }
};

官方的题解为

时间复杂度O(longn)

空间复杂度为O(1)

class Solution {
public:
    bool isPalindrome(int x) {
        // 特殊情况:
        // 如上所述,当 x < 0 时,x 不是回文数。
        // 同样地,如果数字的最后一位是 0,为了使该数字为回文,
        // 则其第一位数字也应该是 0
        // 只有 0 满足这一属性
        if (x < 0 || (x % 10 == 0 && x != 0)) {
            return false;
        }

        int revertedNumber = 0;
        while (x > revertedNumber) {
            revertedNumber = revertedNumber * 10 + x % 10;
            x /= 10;
        }

        // 当数字长度为奇数时,我们可以通过 revertedNumber/10 去除处于中位的数字。
        // 例如,当输入为 12321 时,在 while 循环的末尾我们可以得到 x = 12,revertedNumber = 123,
        // 由于处于中位的数字不影响回文(它总是与自己相等),所以我们可以简单地将其去除。
        return x == revertedNumber || x == revertedNumber / 10;
    }
};

作者:力扣官方题解
链接:https://leetcode.cn/problems/palindrome-number/solutions/281686/hui-wen-shu-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

Leetcode: 268 丢失的数字

用哈希表,查找数字在不在里面

class Solution {
public:
    int missingNumber(vector<int>& nums) {
        int n = nums.size();
        unordered_set<int> L1(nums.begin(),nums.end());
        int i = 0;
        for(i = 0; i <= n; i++){
            if(L1.find(i) == L1.end())
                break;
        }
        return i;

    }
};

或者也可以直接用排序

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

作者:力扣官方题解
链接:https://leetcode.cn/problems/missing-number/solutions/1085105/diu-shi-de-shu-zi-by-leetcode-solution-naow/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

class Solution {
public:
    int missingNumber(vector<int>& nums) {
        int res = 0;
        int n = nums.size();
        for (int i = 0; i < n; i++) {
            res ^= nums[i];
        }
        for (int i = 0; i <= n; i++) {
            res ^= i;
        }
        return res;
    }
};

作者:力扣官方题解
链接:https://leetcode.cn/problems/missing-number/solutions/1085105/diu-shi-de-shu-zi-by-leetcode-solution-naow/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

Leetcode: 771 宝石与石头

直接无脑hash

class Solution {
public:
    int numJewelsInStones(string jewels, string stones) {
        unordered_set<char> L1(jewels.begin(),jewels.end());
        int count = 0;
        for(int i = 0; i < stones.size(); i++){
            if(L1.find(stones[i]) != L1.end()){
                count++;
            }
        }
        return count;


    }
};

Leetcode: 面试题0801 三步问题

第一种解法,简单的动态规划dp,是爬楼梯问题的扩展。

时间复杂度O(N)

空间复杂度O(1)

class Solution {
public:
    int waysToStep(int n) {
         int a=1,b=2,c=4,i;
        for(i=2;i<=n;i++){
            long long t=(a+b)%1000000007;
            t=(t+c)%1000000007;
            a=b;
            b=c;
            c=t;
        }
        return a;
    }
};

第二种解法快速幂

. - 力扣(LeetCode)

就是代码写起来比较难,所以还是建议用动态规划简单求解,但是面试的时候可以说这个方法。

Leetcode:面试题0810 颜色填充

把相邻的元素染成一个颜色。

深度搜索和广度搜索的经典题目,在之前的练习中是岛屿题目。

方法一:广度优先搜索

我们从给定的起点开始,进行广度优先搜索。每次搜索到一个方格时,如果其与初始位置的方格颜色相同,就将该方格加入队列,并将该方格的颜色更新,以防止重复入队。

时间和空间复杂度为O(NM)

class Solution {
public:
    const int dx[4] = {1, 0, 0, -1};
    const int dy[4] = {0, 1, -1, 0};
    vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int newColor) {
        int currColor = image[sr][sc];
        if (currColor == newColor) {
            return image;
		}
        int n = image.size(), m = image[0].size();
        queue<pair<int, int>> que;
        que.emplace(sr, sc);
        image[sr][sc] = newColor;
        while (!que.empty()) {
            int x = que.front().first, y = que.front().second;
            que.pop();
            for (int i = 0; i < 4; i++) {
                int mx = x + dx[i], my = y + dy[i];
                if (mx >= 0 && mx < n && my >= 0 && my < m && image[mx][my] == currColor) {
                    que.emplace(mx, my);
                    image[mx][my] = newColor;
                }
            }
        }
        return image;
    }
};

作者:力扣官方题解
链接:https://leetcode.cn/problems/color-fill-lcci/solutions/1790727/yan-se-tian-chong-by-leetcode-solution-ejum/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

方法二:深度优先搜索

时间和空间复杂度为O(NM)

class Solution {
public:
    const int dx[4] = {1, 0, 0, -1};
    const int dy[4] = {0, 1, -1, 0};
    void dfs(vector<vector<int>>& image, int x, int y, int color, int newColor) {
        if (image[x][y] == color) {
            image[x][y] = newColor;
            for (int i = 0; i < 4; i++) {
                int mx = x + dx[i], my = y + dy[i];
                if (mx >= 0 && mx < image.size() && my >= 0 && my < image[0].size()) {
                    dfs(image, mx, my, color, newColor);
                }
            }
        }
    }

    vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int newColor) {
        int currColor = image[sr][sc];
        if (currColor != newColor) {
            dfs(image, sr, sc, currColor, newColor);
        }
        return image;
    }
};

作者:力扣官方题解
链接:https://leetcode.cn/problems/color-fill-lcci/solutions/1790727/yan-se-tian-chong-by-leetcode-solution-ejum/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

从代码简单程度来看,深度优先搜索的代码写起来简单一点。

Leetcode: 158 内存管理

第一想到是用哈希map来做

class Solution {
public:
    int inventoryManagement(vector<int>& stock) {
        unordered_map<int, int> mp;
        for(int n : stock){
            mp[n]++;
            if(mp[n] > stock.size()/2){
                return n;
            }
        }
        return 0;

    }
};

基于上述的推论,有摩尔法如下:

class Solution {
public:
    int inventoryManagement(vector<int>& stock) {
        int x = 0, votes = 0;
        for(int num : stock){
            if(votes == 0) x = num;
            if(num == x) votes++;
            else votes--;
        }
        return x;
    }
};

Leetcode: LCR120 寻找文件副本

class Solution {
public:
    int findRepeatDocument(vector<int>& documents) {
        unordered_map<int, int> mp;
        for(int n : documents){
            mp[n]++;
            if(mp[n] > 1){
                return n;
            }
        }
        return 0;

    }
};

中等题

Leetcode: 6 Z字形变换

算法基本流程

public:
    string convert(string s, int numRows) {
        if(numRows < 2)
        return s;//处理特殊情况
        vector<string> rows(numRows);
        int i = 0, flag = -1;
        for(char c: s){//把字符串的元素加到对应的行中
            rows[i].push_back(c);
            if(i == 0 || i == numRows - 1)
                flag = -flag;//flag反转,进行模拟
            i += flag;
        }
        string res;
        for(const string &row : rows)
            res += row;//收集最后的结果
        return res;

    }
};

Leetcode:48 旋转矩阵

第一种方法是使用另一个空白的矩阵来存储旋转之后的结果,但是题目要求不能使用,所以要求我们要原地旋转。

使用一个零时变量temp来存储要旋转的位置,保存原来的旋转过去位置的值,然后把那个值放到下一个位置。

. - 力扣(LeetCode)

class Solution {
public:
    void rotate(vector<vector<int>>& matrix) {
        int n = matrix.size();
        for (int i = 0; i < n / 2; ++i) {
            for (int j = 0; j < (n + 1) / 2; ++j) {
                int temp = matrix[i][j];
                matrix[i][j] = matrix[n - j - 1][i];//这是最主要的旋转公式
                matrix[n - j - 1][i] = matrix[n - i - 1][n - j - 1];
                matrix[n - i - 1][n - j - 1] = matrix[j][n - i - 1];
                matrix[j][n - i - 1] = temp;
            }
        }
    }
};

作者:力扣官方题解
链接:https://leetcode.cn/problems/rotate-image/solutions/526980/xuan-zhuan-tu-xiang-by-leetcode-solution-vu3m/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

方法三是使用旋转的方法,先水平翻转,然后对角线翻转。

class Solution {
public:
    void rotate(vector<vector<int>>& matrix) {
        int n = matrix.size();
        // 水平翻转
        for (int i = 0; i < n / 2; ++i) {
            for (int j = 0; j < n; ++j) {
                swap(matrix[i][j], matrix[n - i - 1][j]);
            }
        }
        // 主对角线翻转
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < i; ++j) {
                swap(matrix[i][j], matrix[j][i]);
            }
        }
    }
};

从代码难度上,更喜欢第三种解法。

Leetcode: 92 反转链表2

class Solution {
public:
    ListNode* reverseBetween(ListNode* head, int left, int right) {
        int slow = 0;
        ListNode* dymmyhead = new ListNode(0);
        dymmyhead->next = head;
        ListNode* pre = dymmyhead;
        for(int i = 0; i < left - 1; i++){
            pre = pre->next;//找到开始旋转的起始位置
        }
        ListNode* cur = pre->next;//找到需要断开的位置
        ListNode* node;
        for(int i = 0; i < right - left; i++){
            node = cur->next;
            cur->next = node->next;
            node->next = pre->next;
            pre->next = node;
        }
        return dymmyhead->next;

    }
};

Leetcode:187 重复的DNA序列

我们可以用一个哈希表统计 sss 所有长度为 101010 的子串的出现次数,返回所有出现次数超过 10的子串。为了不重复记录数组,只保存出现==2的字串。

class Solution {
    const int L = 10;
public:
    vector<string> findRepeatedDnaSequences(string s) {
        vector<string> ans;
        unordered_map<string, int> cnt;
        int n = s.length();
        for (int i = 0; i <= n - L; i++) {
            string sub = s.substr(i, L);
            cnt[sub]++;
            if (cnt[sub] == 2) {
                ans.push_back(sub);
            }
        }
        return ans;
    }
};

Leetcode: 852 山脉数组的峰值索引

暴力做法就是找到最大的那个数值就可以。

但是要求复杂度在O(logN),所以可以使用二分法来实现。

class Solution {
public:
    int peakIndexInMountainArray(vector<int>& arr) {
        int left = 0, right = arr.size() - 1;
        int result = 0; 
        while(left <= right){
            int mid = left + (right - left)/2;
            if(arr[mid]>arr[mid-1]&&arr[mid]>arr[mid+1]){
                result = mid;
                break;
            }
            else if(arr[mid] > arr[mid - 1] && arr[mid] < arr[mid + 1]) left = mid;
            else if(arr[mid] > arr[mid + 1] && arr[mid] < arr[mid - 1]) right = mid;
        }
        return result;

    }
};

Leetcode: 22 括号生成

基本的回溯内容。

需要进一步复习。

class Solution {
public:
    vector<string> ans;
    vector<string> generateParenthesis(int n) {
        backtracing(n,"", n, n);
        return ans;
    }
    void backtracing(int n, string str, int left, int right){
        if(left == 0 && right == 0){
            ans.push_back(str);
            return;
        }
        if(left <= right){//剩余的左括号一定要小于等于右括号
            if(left > 0) backtracing(n, str + '(', left - 1, right);
            if(right > 0) backtracing(n, str + ')', left, right - 1);
        }
        else return;
    }
};

Leetcode: 678 有效的括号

第一种方法,两次遍历。

两次遍历 第一次遍历:从前往后遍历确定')',排除类似'))'的情况; 第二次遍历:从后往前遍历确定'(',排除类似'(('的情况; 其余的都符合

class Solution {
public:
    bool checkValidString(string s) {
        int n = s.length();
        int l = 0, m = 0;
        for(int i = 0; i < n; ++i){
            if(s[i] == '('){
                l++;
            }
            else if(s[i] == ')'){
                l--;
            }
            else{
                m++;
            }
            if(l < 0){
                m--;
                l++;
            }
            if(m < 0){
                return false;
            }
        }
        int r = 0;
        m = 0;
        for(int i = n-1; i >=0; --i){
            if(s[i] == ')'){
                r++;
            }
            else if(s[i] == '('){
                r--;
            }
            else{
                m++;
            }
            if(r < 0){
                m--;
                r++;
            }
            if(m < 0){
                return false;
            }
        }
        return true;
    }
};

class Solution {
public:
    bool checkValidString(string s) {
        int minCount = 0, maxCount = 0;
        int n = s.size();
        for (int i = 0; i < n; i++) {
            char c = s[i];
            if (c == '(') {
                minCount++;
                maxCount++;
            } else if (c == ')') {
                minCount = max(minCount - 1, 0);
                maxCount--;
                if (maxCount < 0) {
                    return false;
                }
            } else {
                minCount = max(minCount - 1, 0);
                maxCount++;
            }
        }
        return minCount == 0;
    }
};

作者:力扣官方题解
链接:https://leetcode.cn/problems/valid-parenthesis-string/solutions/992347/you-xiao-de-gua-hao-zi-fu-chuan-by-leetc-osi3/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

当然括号匹配的问题一般都可以用栈来解决

class Solution {
public:
    bool checkValidString(string s) {
        stack<int> leftStack;
        stack<int> asteriskStack;
        int n = s.size();

        for (int i = 0; i < n; i++) {
            char c = s[i];
            if (c == '(') {
                leftStack.push(i);
            } else if (c == '*') {
                asteriskStack.push(i);
            } else {
                if (!leftStack.empty()) {
                    leftStack.pop();
                } else if (!asteriskStack.empty()) {
                    asteriskStack.pop();
                } else {
                    return false;
                }
            }
        }

        while (!leftStack.empty() && !asteriskStack.empty()) {
            int leftIndex = leftStack.top();
            leftStack.pop();
            int asteriskIndex = asteriskStack.top();
            asteriskStack.pop();
            if (leftIndex > asteriskIndex) {
                return false;
            }
        }
        
        return leftStack.empty();
    }
};

作者:力扣官方题解
链接:https://leetcode.cn/problems/valid-parenthesis-string/solutions/992347/you-xiao-de-gua-hao-zi-fu-chuan-by-leetc-osi3/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

Leetcode:215 数组中的第K个最大元素

第一种方法就是很简单的排序然后取n-k个元素就好。

第二种方法:堆排序

建立一个大根堆,做 k−1次删除操作后堆顶元素就是我们要找的答案。

时间复杂度O(nlogn)

空间复杂度O(N)

class Solution {
public:
    void maxHeapify(vector<int>& a, int i, int heapSize) {
        int l = i * 2 + 1, r = i * 2 + 2, largest = i;
        if (l < heapSize && a[l] > a[largest]) {
            largest = l;
        } 
        if (r < heapSize && a[r] > a[largest]) {
            largest = r;
        }
        if (largest != i) {
            swap(a[i], a[largest]);
            maxHeapify(a, largest, heapSize);
        }
    }

    void buildMaxHeap(vector<int>& a, int heapSize) {
        for (int i = heapSize / 2; i >= 0; --i) {
            maxHeapify(a, i, heapSize);
        } 
    }

    int findKthLargest(vector<int>& nums, int k) {
        int heapSize = nums.size();
        buildMaxHeap(nums, heapSize);
        for (int i = nums.size() - 1; i >= nums.size() - k + 1; --i) {
            swap(nums[0], nums[i]);
            --heapSize;
            maxHeapify(nums, 0, heapSize);
        }
        return nums[0];
    }
};

Leetcode: 621 任务调度器

. - 力扣(LeetCode)

时间复杂度 O(nlogn),空间复杂度 O(1)

class Solution {
public:
    int leastInterval(vector<char>& tasks, int n) {
        int len=tasks.size();
        vector<int> vec(26);
        for(char c:tasks) ++vec[c-'A'];
        sort(vec.begin(),vec.end(),[](int& x,int&y){return x>y;});
        int cnt=1;
        while(cnt<vec.size()&&vec[cnt]==vec[0]) cnt++;
        return max(len,cnt+(n+1)*(vec[0]-1) );
    }
};

困难题

  • 12
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值