LeetCode高频面试题记录(六)

剑指 Offer 56 - I. 数组中数字出现的次数 中等

class Solution {
public:
    vector<int> singleNumbers(vector<int>& nums) {
        if (nums.empty()) return {};
        int res = 0;
        for (int num:nums) res ^= num;
        int temp = 1;
        while ((temp & res) == 0)
            temp <<= 1;
        int num1=0, num2=0;
        for (int num:nums){
            if ((temp & num) == 0)//注意&的优先级
                num1 ^= num;
            else
                num2 ^= num;
        }
        return {num1, num2};
    }
};

剑指 Offer 64. 求1+2+…+n 中等

class Solution {
    int sum = 0;
    int Nums(int n) {
        sum += n;
        return n && sumNums(n-1);
    }
public:
    int sumNums(int n) {
        Nums(n);
        return sum;
    }
};

剑指 Offer 47. 礼物的最大价值 中等
记忆化搜索用数组更好理解,二维数组

class Solution {
public:
    vector<vector<int>> memo;
    int dfs(vector<vector<int>>& grid, int i, int j){
        if(i<0 || j<0) 
            return 0;
        if(memo[i][j]!=-1) 
            return memo[i][j];//查询记录 发现就返回
        memo[i][j] = max(dfs(grid, i-1, j), dfs(grid, i, j-1)) + grid[i][j];
        return memo[i][j];
    }
    int maxValue(vector<vector<int>>& grid) {
        memo = vector<vector<int>>(grid.size(),vector<int>(grid[0].size(), -1));
        return dfs(grid,grid.size()-1,grid[0].size()-1);
    }
};

剑指 Offer 58 - I. 翻转单词顺序 简单
仔细体味这段代码

class Solution {
public:
    string reverseWords(string s) {
        if(s.empty())return s;
        int len = 0;
        string ans = "";
        for(int m = s.size()-1; m >=0; m--){//"  hello world!  "
            if(s[m]==' ' && len!=0){
                ans += s.substr(m+1,len)+ " ";
                len = 0; 
                continue;
            }
            if(s[m]!= ' ')len++;
        }
        if(len !=0) ans += s.substr(0,len) + " ";
        if(ans.size()>0)ans.erase(ans.size()-1,1);
        return ans;

    }
};

剑指 Offer 49. 丑数 中等
下面是动态规划讲解
https://leetcode-cn.com/problems/chou-shu-lcof/solution/chou-shu-ii-qing-xi-de-tui-dao-si-lu-by-mrsate/

class Solution {
public:
    int nthUglyNumber(int n) {
        vector<int> dp(n, 0); dp[0] = 1;
        int p2=0, p3=0, p5=0;
        for (int i=1; i<n; i++){
            dp[i] = min(dp[p2]*2, min(dp[p3]*3, dp[p5]*5));
            if (dp[i] == dp[p2]*2) p2++;
            if (dp[i] == dp[p3]*3) p3++;
            if (dp[i] == dp[p5]*5) p5++;
        }
        return dp[n-1];
    }
};

剑指 Offer 59 - I. 滑动窗口的最大值 简单
维护一个双端队列

class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        vector<int> res;
        if (nums.size() < k) return {};
        deque<int> que;
        for (int i=0; i<nums.size(); i++){
            while (!que.empty() && nums[i]>que.back())
                que.pop_back();
            que.push_back(nums[i]);
            if (i >= k-1)
                res.push_back(que.front());
            if (i >= k-1 && que.front() == nums[i-k+1])
                que.pop_front();
        }
        return res;
    }
};

剑指 Offer 53 - II. 0~n-1中缺失的数字 简单
二分法,这个通过动态分析去做,遵循开闭原则

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

剑指 Offer 61. 扑克牌中的顺子 简单

class Solution {
public:
    bool isStraight(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        int start=0;
        for (int i=0; i<nums.size(); i++)
            if (nums[i] != 0){
                start = i;
                break;
            } 
        for (int j=start; j<nums.size()-1; j++)
            if (nums[j] == nums[j+1]) 
                return false;
        return (nums[nums.size()-1]-nums[start] <= 4);
    }
};

剑指 Offer 31. 栈的压入、弹出序列 中等

class Solution {
public:
    bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
        if (pushed.empty())
            return true;
        stack<int> stk; int j=0;
        for (int i=0; i<pushed.size(); i++){  
            stk.push(pushed[i]);       
            while (!stk.empty() && stk.top() == popped[j]){
                stk.pop();
                j++;
            }
        }
        return stk.empty();
    }
};

剑指 Offer 34. 二叉树中和为某一值的路径 中等
记住这种类型的题,大概就是这个模板

class Solution {
    vector<vector<int>> res;
    void path(TreeNode* root, int sum, vector<int> temp){
        if (root == NULL)
            return;
        sum -= root->val; temp.push_back(root->val);
        if (sum == 0 && root->left==NULL && root->right==NULL)
            res.push_back(temp);
        path(root->left, sum, temp);
        path(root->right, sum, temp);
    }
public:
    vector<vector<int>> pathSum(TreeNode* root, int sum) {
        vector<int> temp;
        path(root, sum, temp);
        return res;
    }
};

剑指 Offer 45. 把数组排成最小的数 中等
这道题转换为字符串比较大小

class Solution {
public:
    string minNumber(vector<int>& nums) {
        auto cmp = [](const string a, const string b){return a+b < b+a;};
        vector<string> temp;
        for (int i:nums)
            temp.push_back(to_string(i));
        sort(temp.begin(), temp.end(), cmp);
        string res("");
        for (string s:temp)
            res += s;
        return res;
    }
};

剑指 Offer 14- I. 剪绳子 中等
贪心法

class Solution {
public:
    int cuttingRope(int n) {
        if (n < 4) return n-1;
        int res = 0;
        int num = n / 3;
        int yu = n % 3;
        if (yu == 1)
            return pow(3, num-1)*4;
        if (yu == 2)
            return pow(3, num)*2;
        if (yu == 0)
            return pow(3, num);
        return n;
    }
};
class Solution {
public:
    int cuttingRope(int n) {
        if(n<=3) return n-1;
        int mod = 1000000007;
        long long res = 1;
        while(n > 4 ){
            res *= 3;
            res %= mod;
            n -= 3;
        }
        res = res * n % mod;
        return res;
    }
};

剑指 Offer 38. 字符串的排列 中等
回溯避重模板

class Solution {
    vector<string> res;
    void backTrack(string s, string& temp, vector<bool>& visit){
        if (s.length() == temp.length()){
            res.push_back(temp);
            return;
        }
        for (int i=0; i<s.length(); i++){
            if (visit[i])
                continue;
            if (i > 0 && s[i] == s[i-1] && visit[i-1])
                continue;
            visit[i] = true;
            temp += s[i];
            backTrack(s, temp, visit);
            visit[i] = false;
            temp = temp.substr(0, temp.length()-1);
        }
    }
public:
    vector<string> permutation(string s) {
        vector<bool> visit(s.length(), false);
        string temp("");
        sort(s.begin(), s.end());//先排序,要记住这里
        backTrack(s, temp, visit);
        return res;
    }
};

剑指 Offer 46. 把数字翻译成字符串 中等

class Solution {
public:
    int translateNum(int num) {
        string s = to_string(num);
        vector<int> arr(s.size() + 1, 1);
        arr[0] = 1;
        arr[1] = 1;
        for(int i = 2; i <= s.size(); i++){
            auto a = s.substr(i-2, 2);
            if(a >= "10" && a <= "25")
                arr[i] = arr[i - 1] + arr[i - 2];
            else
                arr[i] = arr[i - 1];
        }
        return arr[s.size()];
    }
};

剑指 Offer 13. 机器人的运动范围 中等
题不难,麻烦认真读题

class Solution {
    int dir[2][2] = {1,0,0,1};
    int BFS(vector<vector<int>>& matrix, int k){
        queue<pair<int,int>> que; que.push(pair<int,int>(0,0));
        int res = 1; matrix[0][0] = 1;
        while (!que.empty()){
            auto temp = que.front();
            que.pop();
            for (int i=0; i<2; i++){
                int x = temp.first + dir[i][0];
                int y = temp.second + dir[i][1];
                if (x >= matrix.size() || y >= matrix[0].size() || x/10+x%10+y/10+y%10>k)
                    continue;
                if (matrix[x][y] == 1){
                    matrix[x][y] = 0;
                    res++;
                    que.push(pair<int,int>(x,y));
                }
            }
        }
        return res;
    }
public:
    int movingCount(int m, int n, int k) {
        vector<vector<int>> matrix(m, vector<int>(n, 1));
        return BFS(matrix, k);
    }
};
class Solution {
    int res = 0;
    void DFS(vector<vector<int>>& matrix, int i, int j, int k){
        if (i<0 || j<0 || i>=matrix.size() || j>=matrix[0].size() || i/10+i%10+j/10+j%10>k)
            return;
        if (matrix[i][j] == 1){
            matrix[i][j] = 0;
            res += 1;
            DFS(matrix,i-1,j,k);
            DFS(matrix,i,j-1,k);
            DFS(matrix,i+1,j,k);
            DFS(matrix,i,j+1,k);
        }
    }
public:
    int movingCount(int m, int n, int k) {
        vector<vector<int>> matrix(m, vector<int>(n, 1));
        DFS(matrix, 0, 0, k);
        return res;
    }
};

剑指 Offer 26. 树的子结构 中等
每次解题发现按照思路写出来的程序还是不对的时候,就举个例子,来顺着程序看步骤对不对,这样就很容易发现问题

class Solution {
    bool SubStructure(TreeNode* A, TreeNode* B){
        if (B == NULL)//注意判断A、B的先后顺序
            return true;
        if (A == NULL)
            return false;
        if (A->val != B->val)
            return false;
        return SubStructure(A->left, B->left) && SubStructure(A->right, B->right);
    }
public:
    bool isSubStructure(TreeNode* A, TreeNode* B) {
        if (A == NULL || B == NULL)
            return false;
        return SubStructure(A,B) || isSubStructure(A->left,B) || isSubStructure(A->right,B);
    }
};

剑指 Offer 12. 矩阵中的路径 中等
记住这个模板

class Solution {
    bool DFS(vector<vector<char>>& board, string word, string& temp, int i, int j){
        if (i<0 || j<0 || i>=board.size() || j>=board[0].size())
            return false;
        bool a, b, c, d;
        if (board[i][j] != '0'){
            auto s = board[i][j];
            temp += s;
            board[i][j] = '0';
            if (temp.length() == word.length() && temp == word)
                return true;
            a = DFS(board,word,temp,i-1,j);
            b = DFS(board,word,temp,i,j-1);
            c = DFS(board,word,temp,i+1,j);
            d = DFS(board,word,temp,i,j+1);
            temp = temp.substr(0,temp.length()-1);
            board[i][j] = s;//这里修改回去
        }
        return a || b || c || d;
    }
public:
    bool exist(vector<vector<char>>& board, string word) {
        bool flag = false;
        for (int i=0; i<board.size(); i++){
            for (int j=0; j<board[0].size(); j++){
                string temp("");
                flag |= DFS(board,word,temp,i,j);
            }
        }
        return flag;
    }
};

剑指 Offer 67. 把字符串转换成整数 中等

class Solution {
public:
    int strToInt(string str) {
        if (str.empty()) return 0;
        while (str[0] == ' ') str = str.substr(1);
        int flag = 1;
        if (str[0] == '-') {str = str.substr(1); flag = -1;}
        else if (str[0] == '+') str = str.substr(1);
        long long res = 0;
        for (int i=0; i<str.length(); i++){
            if (!isdigit(str[i]))
                break;
            res += str[i]-'0';
            if (res >= INT_MAX && flag == 1) return INT_MAX;
            if (res-1 >= INT_MAX && flag == -1) return INT_MIN;
            res *= 10;
        }
        return res/10*flag; 
    }
};

数据流的中位数 困难

class MedianFinder {
    vector<int> nums;
public:
    /** initialize your data structure here. */
    MedianFinder() {

    }
    
    void addNum(int num) {
        if (nums.empty()){
            nums.push_back(num);
            return;
        }
        int left=0, right=nums.size();
        while (left < right){
            int mid = (left + right) / 2;
            if (nums[mid] < num)
                left = mid+1;
            else if (nums[mid] > num)
                right = mid;
            else if (nums[mid] == num){
                left = mid;
                break;
            }//1  2
        }
        nums.insert(nums.begin()+left, num);
    }
    
    double findMedian() {
        if (nums.size() % 2 == 1)
            return nums[nums.size()/2];
        else
            return (nums[nums.size()/2]+nums[nums.size()/2-1])/2.0;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

华为云计算搬砖工

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值