• LeetCode 11-20题解


    11 中等

    Solution

    1. 用i, j(i < j)表示选取的两条线位置, 则水量为((j - i)* min(a_j, a_i))

    2. 我们考虑固定选取的右侧j, 则左侧可选为1...j - 1

    3. (i in [1, j - 1]), 若存在 (k in [1, j - 1] & k < i & a_k >= a_i),

      则有((j - i)* min(a_j, a_i) < (j - k)* min(a_j, a_k)), 右侧固定为j时,左侧k比i更优

    4. 当前位置左侧位置高度均小于当前位置时,当考虑其右侧的位置的左边界时,当前位置时有效候选,无法直接丢弃

    5. 根据以上,可以枚举右侧的j, 左边界用候选集,更新res, 同时更新候选集

    6. 判断左侧高度是否有不小于当前的,用树状数组即可

    Sample Code

    const int maxn = 30010;
    struct Node{
      int pos;
      int val;
    };
    class Solution {
    public:
      vector<Node> Pareto;
      int s[maxn];
      inline int lowbit(int x) { return x & (-x);}
      void add(int x, int v){
          while(x < maxn - 10){
              s[x] += 1;
              x += lowbit(x);
          }
      }
      int get(int x){
          int res = 0;
          while(x){
              res += s[x];
              x -= lowbit(x);
          }
          return res;
      }
      int cal(Node x){
          int res = 0;
          for(Node u : Pareto){
              res = max(res, (x.pos - u.pos) * min(x.val, u.val));
          }
          return res;
      }
      int maxArea(vector<int>& height) {
          int res = 0;
          for(int i = 0; i < height.size(); ++i){
              int curHeight = height[i];
              if(curHeight == 0) continue;
              Node curNode = {i, curHeight};
              res = max(res, cal(curNode));
              if(get(maxn - 10) - get(curHeight - 1) == 0){
                  add(curNode.val, 1);
                  Pareto.push_back(curNode);
              }
          }
          return res;
      }
    };
    

    12 中等

    Solution

    • 模拟

    Sample Code

    char weight[] = {'I', 'V', 'X', 'L', 'C', 'D', 'M'};
    class Solution {
    public: 
        void work(string & res, int x, int bit){
            if(x == 4){
                res += weight[2 * bit];
                res += weight[2 * bit + 1];
                return;
            }
            if(x == 9){
                res += weight[2 * bit];
                res += weight[2 * bit + 2];
                return;
            }
            if(x >= 5) {
                res += weight[2 * bit + 1];
                x -= 5;
            }
            while(x--) res += weight[2 * bit];
        }
        string intToRoman(int num) {
            int _4 = num / 1000;
            int _3 = num % 1000 / 100;
            int _2 = num % 100 / 10;
            int _1 = num % 10;
            string res = "";
            work(res, _4, 3);
            work(res, _3, 2);
            work(res, _2, 1);
            work(res, _1, 0);
            return res;
        }
    };
    

    13 简单

    Solution

    • 简单模拟, 上面逆运算

    Sample Code

    class Solution {
    public:
        int getV(char ch){
            switch(ch){
                case 'I':
                    return 1;
                case 'V':
                    return 5;
                case 'X':
                    return 10;
                case 'L':
                    return 50;
                case 'C':
                    return 100;
                case 'D':
                    return 500;
                case 'M':
                    return 1000;
                default:
                    return -1;
            }
        }
        bool isPreChar(char ch){
            return ch == 'I' || ch == 'X' || ch == 'C';
        }
        bool isPreSuf(char p, char s){
            if(p == 'I') return s == 'V' || s == 'X';
            if(p == 'X') return s == 'L' || s == 'C';
            if(p == 'C') return s == 'D' || s == 'M';
            return false;
        }
        int romanToInt(string s) {
            int res = 0; int len = s.length();
            for(int i = 0; i < s.length(); ++i){
                if(isPreChar(s[i]) && i < len - 1 && isPreSuf(s[i], s[i + 1])){
                    res += getV(s[i + 1]) - getV(s[i]);
                    ++i;
                }else res += getV(s[i]);
            }
            return res;
        }
    };
    

    14 简单

    Solution

    • 可用模拟遍历
    • 用字典树插入

    Sample Code(字典树)

    class Solution {
    public:
        int ch[210 * 210][26];
        int sz = 1;
        int cnt[210 * 210 * 26];
        string ans = "";
        void insert(string s, int len){
            int u = 0;
            for(int i = 0; s[i]; ++i){
                int id = s[i] - 'a';
                if(!ch[u][id]) ch[u][id] = sz++;
                u = ch[u][id];
                ++cnt[u];
                if(cnt[u] == len) ans = s.substr(0, i + 1);
            }
        }
        string longestCommonPrefix(vector<string>& strs) {
            int len = strs.size();
            for(int i = 0; i < len; ++i)
                insert(strs[i], len);
            return ans;
        }
    };
    

    15 中等

    Solution

    • 三指针
    • 排序后枚举固定最右侧,左侧两个位置用二分
    • set去重

    Sample Code

    class Solution {
    public:
        set<vector<int>> resSet; 
        vector<vector<int>> threeSum(vector<int>& nums) {
            int len = nums.size();
            vector<vector<int>> res;
            if(len == 0) return res;
            quickSort(nums, 0, len - 1);
            for(int k = len - 1; k > 1; --k){
                int i = 0, j = k - 1;
                while(i < j){
                    int v = nums[i] + nums[j] + nums[k];
                    if(v == 0){
                        vector<int> candidate;
                        candidate.push_back(nums[i]);
                        candidate.push_back(nums[j]);
                        candidate.push_back(nums[k]);
                        resSet.insert(candidate);
                        if(nums[i] == nums[j]) break;
                        ++i;
                    }
                    if(v > 0) --j;
                    if(v < 0) ++i;
                }
            }
            set<vector<int>>::iterator it;
            for(it = resSet.begin(); it != resSet.end(); ++it)
                res.push_back(*it);
            return res;
        }
        void quickSort(vector<int> & nums, int l, int r){
            if(l == r) return;
            int mid = pivot(nums, l, r);
            if(mid > l) quickSort(nums, l, mid - 1);
            if(mid < r) quickSort(nums, mid + 1, r);
        }
        int pivot(vector<int> & nums, int l, int r){
            int v = nums[l], pos = r;
            while(l < r){
                while(nums[r] >= v && r > l) --r;
                nums[l] = nums[r];
                while(nums[l] <= v && r > l) ++l;
                nums[r] = nums[l];
            }
            nums[l] = v;
            return l;
        }
    };
    

    16 中等

    Solution

    • 二分

    Sample Code

    class Solution {
    public:
        int Abs(int x){
            return x > 0 ? x : -x;
        }
        int threeSumClosest(vector<int>& nums, int target) {
            sort(nums.begin(), nums.end());
            int len = nums.size(); int res = 0x80000000;//稍远的值
            for(int i = 0; i < len - 2; ++i){
                int l = i + 1; int r = len - 1;
                while(l < r){
                    int v = nums[i] + nums[l] + nums[r];
                    if(v == target) return v;
                    if(v < target) ++l;
                    if(v > target) --r;
                    if(res == 0x80000000) res = v;
                    else if(Abs(v - target) < Abs(res - target))
                            res = v;
                }
            }
            return res;
        }
    };
    

    17 中等

    Solution

    • dfs

    Sample Code

    string re[] = {"abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
    class Solution {
    public:
        vector<string> letterCombinations(string digits) {
            vector<string> vecRes; if(digits == "") return vecRes;
            string res = ""; int len = digits.length();
            dfs(vecRes, res, digits, 0, len);
            return vecRes;
        }
        void dfs(vector<string> & vecRes, string res, string & str, int pos, int len){
            if(pos == len){
                vecRes.push_back(res);
                return;
            }
            int x = str[pos] - '0';
            for(int i = 0; re[x - 2][i]; ++i){
                res += re[x - 2][i];
                dfs(vecRes, res, str, pos + 1, len);
                res = res.substr(0, pos);
            }
            
        }
    };
    

    18 中等

    Solution

    • 2sum, 3sum变种
    • 枚举两层 + 2sum

    Sample Code

    class Solution {
    public:
        set<vector<int>> resSet;
        vector<vector<int>> fourSum(vector<int>& nums, int target) {
            int len = nums.size();
            vector<vector<int>> res;
            if(len == 0) return res;
            quickSort(nums, 0, len - 1);
            for(int k = len - 1; k > 2; --k){
                for(int h = k - 1; h > 1; --h){
                    int i = 0, j = h - 1;
                    while(i < j){
                        long long v = (long long)nums[i] + nums[j] + nums[k] + nums[h];
                        if(v == target){
                            vector<int> candidate;
                            candidate.push_back(nums[i]);
                            candidate.push_back(nums[j]);
                            candidate.push_back(nums[k]);
                            candidate.push_back(nums[h]);
                            resSet.insert(candidate);
                            if(nums[i] == nums[j]) break;
                            ++i;
                        }
                        if(v > target) --j;
                        if(v < target) ++i;
                    }
                }
            }
            set<vector<int>>::iterator it;
            for(it = resSet.begin(); it != resSet.end(); ++it)
                res.push_back(*it);
            return res;
        }
        void quickSort(vector<int> & nums, int l, int r){
            if(l == r) return;
            int mid = pivot(nums, l, r);
            if(mid > l) quickSort(nums, l, mid - 1);
            if(mid < r) quickSort(nums, mid + 1, r);
        }
        int pivot(vector<int> & nums, int l, int r){
            int v = nums[l], pos = r;
            while(l < r){
                while(nums[r] >= v && r > l) --r;
                nums[l] = nums[r];
                while(nums[l] <= v && r > l) ++l;
                nums[r] = nums[l];
            }
            nums[l] = v;
            return l;
        }
    };
    

    19 中等

    Solution

    • 双指针一趟遍历
    • 双指针差n个结点

    Sample Code

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode() : val(0), next(nullptr) {}
     *     ListNode(int x) : val(x), next(nullptr) {}
     *     ListNode(int x, ListNode *next) : val(x), next(next) {}
     * };
     */
    class Solution {
    public:
        ListNode* removeNthFromEnd(ListNode* head, int n) {
            ListNode * vHead = new ListNode(0, head);
            ListNode * p = vHead;
            ListNode * q = vHead;
            for(int i = 1; i <= n; ++i) q = q->next;
            while(q->next){
                p = p->next;
                q = q->next;
            }
            p->next = p->next->next;
            return vHead->next;
        }
    };
    

    20 简单

    Solution

    • 栈应用

    Sample Code

    class Solution {
    public:
        bool isRight(char ch){
            return ch == ')' || ch == '}' || ch == ']';
        }
        bool isMapping(char l, char r){
            if(r == ')') return l == '(';
            if(r == ']') return l == '[';
            if(r == '}') return l == '{';
            return false;
        }
        bool isValid(string s) {
            stack<char> sta;
            for(int i = 0; s[i]; ++i){
                if(isRight(s[i])){
                    if(!sta.empty() && isMapping(sta.top(), s[i]))
                        sta.pop();
                    else return false;
                }
                else sta.push(s[i]);
            }
            return sta.empty();
        }
    };
    
    不忘初心
  • 相关阅读:
    weblogic复现利用系列-2019
    weblogic复现利用系列-2020
    Python3编码解码与数据类型转换
    weblogic复现利用系列-2017
    weblogic从ssrf到redis获取shell
    fastjson反序列化复现
    shiro721复现
    Shiro550复现和挖掘思路
    RMI反序列化
    手写一个admin 组件------STARK
  • 原文地址:https://www.cnblogs.com/CodingDreamer/p/15294017.html
Copyright © 2020-2023  润新知