[刷力扣] 31-40题

31. 下一个排列

class Solution {
public:
    void nextPermutation(vector<int>& nums) {
        int i = nums.size() - 2;
        for (; i >= 0 && nums[i] >= nums[i + 1]; -- i);
        int j = nums.size() - 1;
        if (~i) {
            for(; j > i && nums[j] <= nums[i]; -- j);
            swap(nums[i], nums[j]);
        } 
        return reverse(nums.begin() + i + 1, nums.end());
    }
};

32. 最长有效括号

class Solution {
public:
    int longestValidParentheses(string s) {
        int n = s.size(), res = 0;
        vector<int> f(n + 1, 0);
        for (int i = 2; i <= n; ++ i) {
            if (s[i - 1] == ')') {
                if (s[i - 2] == '(') 
                    f[i] = f[i - 2] + 2;
                else if (i - f[i - 1] >= 2 && s[i - f[i - 1] - 2] == '(') 
                    f[i] = f[i - 1] + f[i - f[i - 1] - 2] + 2;
                res = max(f[i], res);
            }
        }
        return res;
    }
};

33. 搜索旋转排序数组

class Solution {
public:
    int search(vector<int>& nums, int target) {
        if (nums.size() == 1) return target == nums.back() ? 0 : -1;
        int l = 0, r = nums.size() - 1;
        while (l < r) {
            int mid = (l + r) >> 1;
            if (nums[0] <= nums[mid]) {
                if (nums[0] <= target && target <= nums[mid]) r = mid;
                else l = mid + 1;
            } else {
                if (nums[mid] < target && target <= nums.back()) l = mid + 1;
                else r = mid;
            }
        }
        if (nums[l] == target) return l;
        return -1;
    }
};

34. 在排序数组中查找元素的第一个和最后一个位置

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        int n = nums.size();
        int l = 0, r = n - 1;
        while (l < r) {
            int mid = (l + r) >> 1;
            if (nums[mid] < target) l = mid + 1;
            else r = mid;
        }
        if (l >= n || nums[l] != target) return {-1, -1};
        int ans = l;
        l = 0, r = n - 1;
        while (l < r) {
            int mid = (l + r + 1) >> 1;
            if (nums[mid] <= target) l = mid;
            else r = mid - 1;
        } 
        return {ans, l};
    }
};

35. 搜索插入位置

class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
        if (nums.back() < target) return nums.size();
        int l = 0, r = nums.size() - 1;
        while (l < r) {
            int mid = (l + r) >> 1;
            if (nums[mid] < target) l = mid + 1;
            else r = mid;
        }
        return r;
    }
};

36. 有效的数独

class Solution {
public:
    bool isValidSudoku(vector<vector<char>>& board) {
        #define N 9
        int l[N] = {0}, r[N] = {0}, mp[N][N] = {0};
        for (int i = 0; i < board.size(); ++ i)
        for (int j = 0; j < board[i].size(); ++ j) {
            if (board[i][j] == '.') continue;
            int t = board[i][j] - '1';
            if (l[i] >> t & 1) return 0;
            if (r[j] >> t & 1) return 0;
            if (mp[i/3][j/3] >> t & 1)  return 0;
            l[i] |= 1 << t;
            r[j] |= 1 << t;
            mp[i/3][j/3] |= 1 << t;
        }
        #undef N
        return 1;
    }
};

37. 解数独

class Solution {
public:
    int tag = 0;
    void dfs (int x, int y, int l[], int r[], int mp[][9], vector<vector<char>>& board) {
        if (tag) return;
        if (x >= 9) {
            tag = 1;
            return;
        }
        if (y >= 9) dfs (x + 1, 0, l, r, mp, board);
        else if (board[x][y] != '.') dfs(x, y + 1, l, r, mp, board);
        else {
            for (int i = 0; i < 9 && !tag; ++ i) {
                if (l[x] >> i & 1) continue;
                if (r[y] >> i & 1) continue;
                if (mp[x / 3][y / 3] >> i & 1) continue;
                l[x] += 1 << i;
                r[y] += 1 << i;
                mp[x / 3][y / 3] += 1 << i;
                board[x][y] = '1' + i;
                dfs (x, y + 1, l, r, mp, board);
                if (!tag) board[x][y] = '.';
                l[x] -= 1 << i;
                r[y] -= 1 << i;
                mp[x / 3][y / 3] -= 1 << i;
            }
        }
    }
    void solveSudoku(vector<vector<char>>& board) {
        #define N 9
        int l[N] = {0}, r[N] = {0}, mp[N][N] = {0};
        tag = 0;
        for (int i = 0; i < board.size(); ++ i)
        for (int j = 0; j < board[i].size(); ++ j) {
            if (board[i][j] == '.') continue;
            int t = board[i][j] - '1';
            l[i] += 1 << t;
            r[j] += 1 << t;
            mp[i/3][j/3] += 1 << t;
        }
        dfs (0, 0, l, r, mp, board);
        #undef N
    }
};

38. 外观数列

class Solution {
public:
    string countAndSay(int n) {
        string s = "1";
        for (int i = 2; i <= n; ++ i) {
            string te;
            char ch = s[0];
            int st = 1;
            for (int j = 1; j < s.size(); ++ j) {
                if (s[j] != s[j - 1]) {
                    te += to_string(st);te.push_back(ch);
                    ch = s[j], st = 1;
                } else st ++;
            }
            te += to_string(st);te.push_back(ch);
            s = te;
        }
        return s;
    }
};

39. 组合总和


class Solution {
public:
    void dfs (int cur, int val, int target, vector<int>& temp, vector<int>& g, vector<vector<int>>& ans) {
        if (cur >= g.size()) return;
        if (val == target) {
            ans.push_back(temp);
            return;
        }
        if (val > target) return;
        if (val + g[cur] <= target) {
            temp.push_back(g[cur]);
            dfs(cur, val + g[cur], target, temp, g, ans);
            temp.pop_back();
        }
        dfs(cur + 1, val, target, temp, g, ans);
    }
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        vector<vector<int>> ans;
        vector<int> temp;
        dfs (0, 0, target, temp, candidates, ans);
        return ans;
    }
};

40. 组合总和 II

class Solution {
public:
    void dfs (int cur, int val, int target, vector<int>& temp, vector<int>& g, vector<vector<int>>& ans) {
        if (val > target) return;
        if (val == target) {
            ans.push_back(temp);
            return;
        }
        if (cur >= g.size()) return;
        for (int i = cur; i < g.size(); ++ i) {
            if (i != cur && g[i] == g[i - 1]) continue;
            temp.push_back(g[i]);
            dfs(i + 1, val + g[i], target, temp, g, ans);
            temp.pop_back();
        }
    }
    vector<vector<int>> combinationSum2(vector<int>& g, int target) {
        vector<vector<int>> ans;
        vector<int> temp;
        sort(g.begin(), g.end());
        dfs (0, 0, target, temp, g, ans);
        return ans;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值