2020-7-14

312. 戳气球

题解: 动态规划,区间DP, dp[i][j] 代表戳破 (i,j)这段气球所能获得的最大价值 (开区间)。

状态转移方程 dp[i][j] = max(dp[i][j], dp[i][k]+dp[k][j]+nums[i]*nums[k]*nums[j]),此时 k 是最后一个戳破的,(i,k) (k,j)都已经被戳破了。
class Solution {
public:
    int dp[505][505]; // dp[i][j] 代表戳破 (i,j)这段气球所能获得的最大价值
    // 状态转移方程 dp[i][j] = max(dp[i][j], dp[i][k]+dp[k][j]+nums[i]*nums[k]*nums[j])
    // 此时 k 是最后一个戳破的,(i,k) (k,j)都已经被戳破了
    int maxCoins(vector<int>& nums) {
        if(nums.size()==0) return 0;
        nums.insert(nums.begin(),1);
        nums.push_back(1);
        for(int l=1;l<=nums.size();l++){
            for(int i=0; i+l-1<nums.size();i++){
                int j = i+l-1;
                for(int k=i+1; k<j;k++){
                    dp[i][j] = max(dp[i][j], dp[i][k]+dp[k][j]+nums[i]*nums[k]*nums[j]);
                }
            }
        }
        return dp[0][nums.size()-1];
    }
};
View Code

面试题 17.15. 最长单词

题解: 搜索,对每一个单词进行拆分,看能否拆分为多个单词。

class Solution {
public:
    unordered_set <string> wordset;
    bool split(string s){
        //cout << s << endl;
        if(s.size()==0) return true;
        for(int i=1;i<=s.size();i++){
            if(wordset.count(s.substr(0,i)) && split(s.substr(i)) ) return true;
        }
        return false;
    }
    string longestWord(vector<string>& words) {
        sort(words.begin(), words.end(), [](const string & a, const string & b) -> bool{ 
            if(a.size()==b.size()) return a < b;
            return a.size() > b.size();
        });
        for(auto word: words) wordset.insert(word);
        for(int i=0;i<words.size();i++){
            wordset.erase(words[i]);
            if(split(words[i])) return words[i];
        }
        return "";
    }
};
View Code

752. 打开转盘锁

题解: 搜索,枚举所有状态。

class Solution {
public:
    unordered_set<string> words;
    bool vis[10][10][10][10];
    int openLock(vector<string>& deadends, string target) {
        for(auto x: deadends) words.insert(x);
        if(words.count("0000")) return -1;
        queue <pair<string, int> > q;
        q.push({"0000", 0});
        vis[0][0][0][0] = 1;
        while(q.size()){
            pair<string, int> now = q.front(); q.pop();
            if(now.first==target) return now.second;
            string next;
            for(int i=0;i<4;i++){
                next = now.first;
                if(next[i]<'9')next[i] = next[i] + 1;
                else next[i] = '0';
                if(words.count(next)) continue;
                //cout << now << " " << next << endl;
                if(vis[next[0]-'0'][next[1]-'0'][next[2]-'0'][next[3]-'0']) continue;
                vis[next[0]-'0'][next[1]-'0'][next[2]-'0'][next[3]-'0'] = 1;
                q.push({next, now.second+1});
            }
            for(int i=0;i<4;i++){
                next = now.first;
                if(next[i]>'0')next[i] = next[i] - 1;
                else next[i] = '9';
                if(words.count(next)) continue;
                //cout << now << " " << next << endl;
                if(vis[next[0]-'0'][next[1]-'0'][next[2]-'0'][next[3]-'0']) continue;
                vis[next[0]-'0'][next[1]-'0'][next[2]-'0'][next[3]-'0'] = 1;
                q.push({next, now.second+1});
            }
        }
        return -1;
    }
};
View Code

938. 二叉搜索树的范围和

题解: 搜索

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int rangeSumBST(TreeNode* root, int L, int R) {
        if(!root) return 0;
        int val_l = rangeSumBST(root->left, L , R);
        int val_root = 0;
        if(root->val >= L && root->val <=R) val_root = root->val;
        int val_r = rangeSumBST(root->right, L, R);
        return val_l+val_root+val_r;
    }
};
View Code

861. 翻转矩阵后的得分

题解: 贪心算法,首先我们得明确一点,一个位置肯定只能变换1次,翻转多次的话没有意义。第二,每一行的第一个数都得是1, 第三,保证第二点的基础上第每一列的1尽可能多。

class Solution {
public:
    int matrixScore(vector<vector<int>>& A) {
        int rownum = A.size() , colnum = A[0].size();
        for(int i=0;i<rownum;i++){ // 每一行的第一个数都得为 1 ,才能保证最终的结果尽可能大
            if(A[i][0]==0){
                for(int j=0;j<colnum;j++) A[i][j] = 1-A[i][j];
            }
        }
        for(int i=1;i<colnum;i++){ // check 一下每一列的1的个数
            int num = 0;
            for(int j=0;j<rownum;j++){
                if(A[j][i]==1) num++;
            }
            if(num <= rownum/2){
                for(int j=0;j<rownum;j++) A[j][i] = 1- A[j][i];
            }
        }
        int ans = 0;
        for(int i=0;i<rownum;i++){
            int now = 0, base = 1;
            for(int j=colnum-1;j>=0;j--){
                //printf("%d\n",A[i][j]);
                now = now + A[i][j]*base;
                base*=2;
                //printf("%d\n",now);
            }
           
            ans += now;
        }
        return ans;
    }
};
View Code

 

posted @ 2020-07-19 16:08  樱花庄的龙之介大人  阅读(165)  评论(0编辑  收藏  举报