LeetCode高频面试题记录(七)

四数之和 中等

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        sort(nums.begin(),nums.end());
        vector <vector<int>> res;
        for(int i = 0; i + 3 < nums.size(); ++i){
            if(i > 0 && nums[i] == nums[i-1])   
                continue;
            for(int j = i+1; j + 2 < nums.size(); ++j){
                if(j > i+1 && nums[j] == nums[j-1])   
                    continue; 
                //此处不能为j>0,循环至少进行一轮后才能continue,确保当前情况已经判断过
                int ttarget = target - nums[i] - nums[j] ;
                int l = j+1, r = nums.size()-1;
                while(l < r){
                    int sum = nums[l] + nums[r];        //注意-号
                    if(ttarget == sum){
                        res.push_back({nums[i],nums[j],nums[l],nums[r]});
                        l++; r--;
                        while(l < r && nums[l] == nums[l-1])    l++;
                        while(l < r && nums[r] == nums[r+1])    r--;
                    }
                    if(ttarget > sum)    l++;
                    if(ttarget < sum)    r--;
                } 
            }
        }
        return res;
    }
};

寻找峰值 中等
暂时还不知道二分法有什么好的模板
细节是魔鬼

class Solution {
public:
    int findPeakElement(vector<int>& nums) {
        int left = 0;
        int right = nums.size()-1;
        while(left < right){
            int mid = (right + left) / 2;
            if (nums[mid] > nums[mid+1])
                right = mid;
            else
                left = mid + 1;
        }
        return left;
    }
};
  1. 二叉树的直径 简单
class Solution {
    int ans = 0;
    int depth(TreeNode* root){
        if (root == NULL)
            return 0;
        int l = depth(root->left);
        int r = depth(root->right);
        ans = max(ans, l+r);
        return max(l, r)+1;
    }
public:
    int diameterOfBinaryTree(TreeNode* root) {
        if (root == NULL) return 0;
        depth(root);
        return ans;
    }
};

组合总和

class Solution {
public:
    vector<vector<int>> res;
    void backTrack(int now, int sum, int target, vector<int> temp, vector<int>& candidates){
        if(sum > target) return;
        if(sum == target){
            res.push_back(temp);
            return;
        }
        for(int i=now; i<candidates.size(); i++){
            sum += candidates[i];
            temp.push_back(candidates[i]);
            backTrack(i, sum, target, temp, candidates);
            sum -= candidates[i];
            temp.pop_back();
        }
    }
    vector<vector<int>> combinationSum(vector<int>& candidates, int target){
        vector<int> temp;
        backTrack(0, 0, target, temp, candidates);
        return res;
    }
};

旋转图像 中等

class Solution {
public:
    void rotate(vector<vector<int>>& matrix) {
        if (matrix.empty()) return;
        int n = matrix.size(); int m = matrix[0].size();
        for (int i=0; i<=(n-1)/2; i++){
            for (int j=0; j<m/2; j++){
                int temp = matrix[i][j];
                matrix[i][j] = matrix[n-1-j][i];
                matrix[n-1-j][i] = matrix[n-1-i][m-1-j];
                matrix[n-1-i][m-1-j] = matrix[j][n-1-i];
                matrix[j][n-1-i] = temp;
            }
        }
    }
};

实现 Trie (前缀树) 中等

class Trie {
    bool flag = false;
    Trie* str[26] = {nullptr};
public:
    /** Initialize your data structure here. */
    Trie() {

    }
    
    /** Inserts a word into the trie. */
    void insert(string word) {
        Trie* root = this;
        for (auto c:word){
            if (root->str[c-'a'] == nullptr) root->str[c-'a'] = new Trie();
            root = root->str[c-'a'];
        }
        root->flag = true;
    }
    
    /** Returns if the word is in the trie. */
    bool search(string word) {
        Trie* root = this;
        for (auto c:word){
            if (root->str[c-'a'] == nullptr) return false;
            root = root->str[c-'a'];
        }
        return root->flag;
    }
    
    /** Returns if there is any word in the trie that starts with the given prefix. */
    bool startsWith(string prefix) {
        Trie* root = this;
        for (auto c:prefix){
            if (root->str[c-'a'] == nullptr) return false;
            root = root->str[c-'a'];
        }
        return true;
    }
};

根据身高重建队列 中等

class Solution {
public:
	vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
        auto cmp = [](vector<int>a, vector<int>b){
			return (a[0] > b[0]) || (a[0] == b[0] && a[1] < b[1]);};
		sort(people.begin(), people.end(), cmp);
		vector<vector<int>> ans;
		for(int i = 0; i < people.size(); i++)
			//局部最优
			ans.insert(ans.begin() + people[i][1], people[i]);
		return ans;
	}
};

字母异位词分组

class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        unordered_map<string, vector<string>> map;
        for (auto s:strs){
            string temp(s);
            sort(temp.begin(), temp.end());//这里排序是精髓
            map[temp].push_back(s);
        }
        vector<vector<string>> res;
        for (auto i:map){
            vector<string> temp(i.second.begin(), i.second.end());
            res.push_back(temp);
        }
        return res;
    }
};

回文子串

class Solution {
    int helper(string s, int l, int r){
        int res = 0;
        while (l>=0 && r<s.length() && s[l] == s[r]){
            res++;
            l--; r++;
        }
        return res;
    }
public:
    int countSubstrings(string s) {
        if (s.empty()) return 0;
        int res = 0;
        for (int i=0; i<s.length(); i++){
            res += helper(s, i, i);
            res += helper(s, i, i+1);
        }
        return res;
    }
};

前 K 个高频元素

class Solution {
public:
    vector<int> topKFrequent(vector<int>& nums, int k) {
        unordered_map<int, int> map;
        for (auto n:nums)
            map[n]++;
        auto mycmp = [](pair<int,int> a, pair<int,int> b){return a.second > b.second;};
        priority_queue<pair<int,int>, vector<pair<int,int>>, decltype(mycmp)> que(mycmp);
        for (auto i:map){
            if (que.empty() || k) {//在这里进行k的控制
                que.push(i);
                k--;
            }
            else{
                if (i.second > que.top().second){
                    que.pop();
                    que.push(i);
                }
            }
        }
        vector<int> res;
        while (!que.empty()){
            auto temp = que.top();
            que.pop();
            res.push_back(temp.first);
        }
        return res;
    }
};

打家劫舍 III

struct SubtreeStatus {
    int selected;
    int notSelected;
};
class Solution {
public:
    SubtreeStatus dfs(TreeNode* root) {
        if (root == NULL) 
            return {0, 0};
        auto l = dfs(root->left);
        auto r = dfs(root->right);
        int selected = root->val + l.notSelected + r.notSelected;
        int notSelected = max(l.selected, l.notSelected) + max(r.selected, r.notSelected);
        return {selected, notSelected};
    }

    int rob(TreeNode* root) {
        auto rootStatus = dfs(root);
        return max(rootStatus.selected, rootStatus.notSelected);
    }
};

完全平方数
转化为背包问题

class Solution {
public:
    int numSquares(int n) {
        vector<int> coins(sqrt(n)+1);
        for (int i=1; i<coins.size(); i++)
            coins[i] = i*i;
        vector<int> dp(n+1, n+1); dp[0]=0;
        for (int i=1; i<=n; i++){
            for (int j=0; j<coins.size(); j++){
                if (i >= coins[j])
                    dp[i] = min(dp[i], dp[i-coins[j]]+1);
            }
        }
        return dp[n] > n ? -1 : dp[n];
    }
};

路径总和 III

class Solution {
    int res = 0;
    void path(TreeNode* root, int sum){
        if (root == nullptr) return;
        sum -= root->val;
        if (sum == 0)
            res++;
        path(root->left, sum);
        path(root->right, sum);
    }
public:
    int pathSum(TreeNode* root, int sum) {
        if (root == nullptr) return 0;
        path(root, sum);
        pathSum(root->left, sum);
        pathSum(root->right, sum);
        return res;
    }
};

颜色分类

class Solution {
public:
    void sortColors(vector<int>& nums) {
        int p0 = 0, curr = 0;
        int p2 = nums.size() - 1;

        while (curr <= p2) {
            if (nums[curr] == 0) {
                swap(nums[curr++], nums[p0++]);
            }
            else if (nums[curr] == 2) {
                swap(nums[curr], nums[p2--]);
            }
            else curr++;
        }
    }
};

电话号码的字母组合

class Solution {
    unordered_map<char, string> map;
    vector<string> res;
    void backTrack(string digits, string& temp, int index){
        if (digits.length() == index){
            res.push_back(temp);
            return;
        }
        for (int i=0; i<map[digits[index]].length(); i++){
            temp += map[digits[index]][i];
            backTrack(digits, temp, index+1);
            temp.pop_back();
        }
    }
public:
    vector<string> letterCombinations(string digits) {
        map['2'] = "abc"; map['3'] = "def"; map['4'] = "ghi"; map['5'] = "jkl";
        map['6'] = "mno"; map['7'] = "pqrs"; map['8'] = "tuv"; map['9'] = "wxyz";
        if (digits.empty()) return {};
        string temp("");
        backTrack(digits, temp, 0);
        return res;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

华为云计算搬砖工

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

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

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

打赏作者

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

抵扣说明:

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

余额充值