Leetcode problem-solving ideas analysis (40) 335-343

  1. Path intersection
    Given an array x containing n positive numbers. Starting at point (0,0), first move x[0] meters north, then x[1] meters west, x[2] meters south, x[3] meters east, and continue moving. In other words, your position will change counterclockwise after each movement.
    Write a one-pass scanning algorithm with O(1) space complexity to determine whether the paths you travel through intersect.

The key to this question is to draw a picture to analyze the situation where various types will intersect, and finally summarize the solution

class Solution {
    
    
public:
    bool isSelfCrossing(vector<int>& x) {
    
    
        int x_size=x.size();
        for (int i=3;i<x_size;++i)
        {
    
    
            if (i>=3 && x.at(i-1)<=x.at(i-3) && x.at(i)>=x.at(i-2))
                return true;
            if (i>=4 && x.at(i-3)==x.at(i-1) && x.at(i)+x.at(i-4)>=x.at(i-2))
                return true;
            if (i>=5 && x.at(i)+x.at(i-4)>=x.at(i-2) && x.at(i-1)+x.at(i-5)>=x.at(i-3) 
            && x.at(i-2)>x.at(i-4) && x.at(i-3)>x.at(i-1))
                return true;
        }
        return false;
    }
};

  1. A palindrome pair is
    given a group of different words, find all the different index pairs (i, j), so that the two words in the list, words[i] + words[j], can be spliced ​​into a palindrome string .

The main focus of this question is: if s1 + s2 can form a palindrome pair, then either s1 is long or s2 is long or two are equal in length. The long one must have palindrome substrings and the other one-time reverse order. You can use a horse-drawn cart or brute force search to find a substring palindrome, and you can use a hash table or letter number to store other strings in reverse order

struct Trie {
    
    
    struct node {
    
    
        int ch[26];
        int flag;
        node() {
    
    
            flag = -1;
            memset(ch, 0, sizeof(ch));
        }
    };

    vector<node> tree;

    Trie() {
    
     tree.emplace_back(); }

    void insert(string& s, int id) {
    
    
        int len = s.length(), add = 0;
        for (int i = 0; i < len; i++) {
    
    
            int x = s[i] - 'a';
            if (!tree[add].ch[x]) {
    
    
                tree.emplace_back();
                tree[add].ch[x] = tree.size() - 1;
            }
            add = tree[add].ch[x];
        }
        tree[add].flag = id;
    }

    vector<int> query(string& s) {
    
    
        int len = s.length(), add = 0;
        vector<int> ret(len + 1, -1);
        for (int i = 0; i < len; i++) {
    
    
            ret[i] = tree[add].flag;
            int x = s[i] - 'a';
            if (!tree[add].ch[x]) {
    
    
                return ret;
            }
            add = tree[add].ch[x];
        }
        ret[len] = tree[add].flag;
        return ret;
    }
};

class Solution {
    
    
public:
    vector<pair<int, int>> manacher(string& s) {
    
    
        int n = s.length();
        string tmp = "#";
        tmp += s[0];
        for (int i = 1; i < n; i++) {
    
    
            tmp += '*';
            tmp += s[i];
        }
        tmp += '!';
        int m = n * 2;
        vector<int> len(m);
        vector<pair<int, int>> ret(n);
        int p = 0, maxn = -1;
        for (int i = 1; i < m; i++) {
    
    
            len[i] = maxn >= i ? min(len[2 * p - i], maxn - i) : 0;
            while (tmp[i - len[i] - 1] == tmp[i + len[i] + 1]) {
    
    
                len[i]++;
            }
            if (i + len[i] > maxn) {
    
    
                p = i, maxn = i + len[i];
            }
            if (i - len[i] == 1) {
    
    
                ret[(i + len[i]) / 2].first = 1;
            }
            if (i + len[i] == m - 1) {
    
    
                ret[(i - len[i]) / 2].second = 1;
            }
        }
        return ret;
    }

    vector<vector<int>> palindromePairs(vector<string>& words) {
    
    
        Trie trie1, trie2;

        int n = words.size();
        for (int i = 0; i < n; i++) {
    
    
            trie1.insert(words[i], i);
            string tmp = words[i];
            reverse(tmp.begin(), tmp.end());
            trie2.insert(tmp, i);
        }

        vector<vector<int>> ret;
        for (int i = 0; i < n; i++) {
    
    
            const vector<pair<int, int>>& rec = manacher(words[i]);

            const vector<int>& id1 = trie2.query(words[i]);
            reverse(words[i].begin(), words[i].end());
            const vector<int>& id2 = trie1.query(words[i]);

            int m = words[i].size();

            int all_id = id1[m];
            if (all_id != -1 && all_id != i) {
    
    
                ret.push_back({
    
    i, all_id});
            }
            for (int j = 0; j < m; j++) {
    
    
                if (rec[j].first) {
    
    
                    int left_id = id2[m - j - 1];
                    if (left_id != -1 && left_id != i) {
    
    
                        ret.push_back({
    
    left_id, i});
                    }
                }
                if (rec[j].second) {
    
    
                    int right_id = id1[j];
                    if (right_id != -1 && right_id != i) {
    
    
                        ret.push_back({
    
    i, right_id});
                    }
                }
            }
        }
        return ret;
    }
};

  1. House Robber 3

Dynamic programming is solvable, and each node can be selected or not. If you don't select it, you can select its child nodes, otherwise you can't.

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
struct SubtreeStatus {
    
    
    int selected;
    int notSelected;
};

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

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

  1. Bit count
    Given a non-negative integer num. For each number i in the range 0 ≤ i ≤ num, count the number of 1s in its binary number and return them as an array.

For a number and one-half of it, it is actually a shift operation. The difference in the number of numbers 1 is the last digit, so the bit operation can be used.

class Solution {
    
    
public:
    vector<int> countBits(int num) {
    
    
        vector<int> ret(num + 1);
        for (int i = 1; i <= num; ++i)
            ret[i] = ret[i >> 1] + (i & 1); // x / 2 is x >> 1 and x % 2 is x & 1
        return ret;
    }
};
  1. The flattened nested list iterator
    gives you a nested list of integers. Please design an iterator so that it can traverse all integers in this integer list. Each item in the list is either an integer or another list. The elements of the list may also be integers or other lists

Traverse it once

class NestedIterator {
    
    
public:
    vector<int> data;
    vector<int>::iterator it;
    NestedIterator(vector<NestedInteger> &nestedList) {
    
    
        parse(nestedList);
        it = data.begin();
    }
    
    void parse(vector<NestedInteger> &nestedList){
    
    
        for(auto nes : nestedList){
    
    
            if(nes.isInteger()) data.push_back(nes.getInteger());
            else parse(nes.getList());
        }
    }

    int next() {
    
    
        return *it++;
    }
    
    bool hasNext() {
    
    
        return it != data.end();
    }
};
  1. Power of 4
    Given an integer (32-bit signed integer), write a function to determine whether it is a power of 4.

The power of 4 must be the power of 2, but the power of 2 is not necessarily the power of 4. Through the binary of the power of 4, it can be found that the power of 4 in the binary number 1 only appears in odd numbers. Bit. Therefore, it is possible to perform the AND operation on the numbers (1010101010101010101010101010101) where the odd digits are all 1, and the even numbers are all 0, and the result is still the original number.

class Solution {
    
    
public:
    bool isPowerOfFour(int num) {
    
    
        return num > 0 && !(num & (num - 1)) && (num & 0x55555555) == num;
    }
};


  1. Integer Splitting
    Given a positive integer n, split it into the sum of at least two positive integers, and maximize the product of these integers. Returns the largest product you can get.

This problem can be solved by a greedy algorithm, but the best solution is definitely to derive the mathematical law and directly seek the maximum value

class Solution {
    
    
public:
    int integerBreak(int n) {
    
    
        if (n <= 3) {
    
    
            return n - 1;
        }
        int quotient = n / 3;
        int remainder = n % 3;
        if (remainder == 0) {
    
    
            return (int)pow(3, quotient);
        } else if (remainder == 1) {
    
    
            return (int)pow(3, quotient - 1) * 4;
        } else {
    
    
            return (int)pow(3, quotient) * 2;
        }
    }
};


Guess you like

Origin blog.csdn.net/u013354486/article/details/108348931