Skip to content

Latest commit

 

History

History
437 lines (420 loc) · 12.3 KB

3.17.2017(Q46-Q60).md

File metadata and controls

437 lines (420 loc) · 12.3 KB

Questions 45 ~ 60

46, Permutations

Question: Given a collection of distinct numbers, return all possible permutations.
Idea: use recursive:
typedef vector<int> vi;
class Solution {
    vector<vi> perm(vi &A,int k){
        vector<vi> ans;
        if(k==0) return vector<vi>{vi{A[0]}};
        vector<vi> tmp = perm(A,k-1);
        for(auto vec:tmp){
            for(int i=0;i<=k;++i){
                vi B(vec.begin(),vec.begin()+i);
                B.push_back(A[k]);
                for(int j=i;j<k;++j) B.push_back(vec[j]);
                ans.push_back(B);
            }
        }
        return ans;
    }
public:
    vector<vector<int>> permute(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        return perm(nums,nums.size()-1);
    }
};

47, Permutations II

Question: Given a collection of numbers that might contain duplicates, return all possible unique permutations.
Idea: Still using recursive, however, every time when we need to insert, we maintain the order of duplicates numbers.
typedef vector<int> vi;
class Solution {
    vector<vi> perm(vi &A,int k){
        vector<vi> ans;
        if(!k) return vector<vi>{vi{A[0]}};
        vector<vi> old = perm(A,k-1);
        int st = 0;
        for(auto vec:old){
            if(A[k]==A[k-1]){
                st = k;
                while(vec[st-1]!=A[k]) --st;
            }
            for(int i=st;i<=k;++i){
                vi tmp(vec.begin(),vec.begin()+i);
                tmp.push_back(A[k]);
                for(int j=i;j<k;++j) tmp.push_back(vec[j]);
                ans.push_back(tmp);
            }
        }
        return ans;
    }
public:
    vector<vector<int>> permuteUnique(vector<int>& nums) {
        if(nums.empty()) return vector<vi>();
        sort(nums.begin(), nums.end());
        return perm(nums,nums.size()-1);
    }
};

48, Rotate Image

Question: You are given an n x n 2D matrix representing an image. Rotate the image by 90 degrees (clockwise).
Idea: 2 X mirror image: one about y plane, one about the diagnal
class Solution {
public:
    void rotate(vector<vector<int>>& matrix) {
        int n = matrix.size();
        for(int i=0;i<n/2;++i) swap(matrix[i],matrix[n-i-1]);
        for(int i=0;i<n;++i) for(int j=0;j<i;++j) swap(matrix[i][j],matrix[j][i]);
    }
};

49, Group Anagrams

Question: Given an array of strings, group anagrams together.
Method #1: from map to map:
class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        map<map<char,int>, vector<string>> cnt;
        for(auto s:strs){
            map<char,int> tmp;
            for(auto c:s) tmp[c]++;
            cnt[tmp].push_back(s);
        }
        vector<vector<string>> ans;
        for(auto p:cnt) ans.push_back(p.second);
        return ans;
    }
};
Method #2: use string to create map:
class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        unordered_map<string, vector<string>> cnt;
        for(auto s:strs){
            string tmp = s;
            sort(tmp.begin(),tmp.end());
            cnt[tmp].push_back(s);
        }
        vector<vector<string>> ans;
        for(auto p:cnt) ans.push_back(p.second);
        return ans;
    }
};

50, Pow(x, n)

Question: Implement pow(x, n).
Idea: Easy
class Solution {
public:
    double myPow(double x, int n) {
        double ans = 1.;
        int sign = n>=0?1:-1;
        n *= sign;
        while(n){
            if(n%2) ans *= x;
            x *= x;
            n /= 2;
        }
        if(sign==-1) ans = 1./ans;
        return ans;
    }
};

51, N-Queens

Question: The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens attack each other.
[
 [".Q..",  // Solution 1
  "...Q",
  "Q...",
  "..Q."],

 ["..Q.",  // Solution 2
  "Q...",
  "...Q",
  ".Q.."]
]
Idea: Use dfs and keep checking: x,y,xy,yx
typedef vector<int> vi;
typedef vector<bool> vb;
typedef vector<string> vs;
class Solution {
    vector<vb> dp;
    void wtf(vector<vi> &ans,vi cur,int k){
        if(k == cur.size()){
            ans.push_back(cur);
            return;
        }
        for(int i=0;i<cur.size();++i){
            if(dp[0][i] && dp[1][k+i] && dp[2][k-i+cur.size()]){
                dp[0][i] = dp[1][k+i] = dp[2][k-i+cur.size()] = false;
                cur[k] = i;
                wtf(ans,cur,k+1);
                dp[0][i] = dp[1][k+i] = dp[2][k-i+cur.size()] = true;
            }
        }
        return;
    }
public:
    vector<vector<string>> solveNQueens(int n) {
        dp = vector<vb>(3,vb(2*n+1,true));
        vector<vs> config;
        vector<vi> ans;
        wtf(ans,vi(n,-1),0);
        for(auto vec:ans){
            vs tmp(n,string(n,'.'));
            for(int i=0;i<n;++i) tmp[i][vec[i]] = 'Q';
            config.push_back(tmp);
        }
        return config;
    }
};

52, N-Queens II

Question: Follow up for N-Queens problem. Now, instead outputting board configurations, return the total number of distinct solutions.
Idea, The same dfs + recursive
typedef vector<bool> vb;
class Solution {
    vector<vb> dp;
    void whatTheFuck(int &ans,int k,int &n){
        if(k==n){
            ++ans;
            return;
        }
        for(int i=0;i<n;++i) if(dp[0][i] && dp[1][k+i] && dp[2][n+k-i]){
            dp[0][i] = dp[1][k+i] = dp[2][n+k-i] = false;
            whatTheFuck(ans,k+1,n);
            dp[0][i] = dp[1][k+i] = dp[2][n+k-i] = true;
        }
    }
public:
    int totalNQueens(int n) {
        dp = vector<vb>(3,vb(2*n+1,true));
        int ans;
        whatTheFuck(ans,0,n);
        return ans;
    }
};

53, Maximum Subarray

Question: Find the contiguous subarray within an array (containing at least one number) which has the largest sum. For example, given the array [-2,1,-3,4,-1,2,1,-5,4], the contiguous subarray [4,-1,2,1] has the largest sum = 6.
Idea: partial sum:
class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int n = nums.size(), ans = nums[0];
        vector<int> P(n+1,0);
        for(int i=1;i<=n;++i) P[i] = P[i-1] + nums[i-1];
        for(int i=1,tmp=0;i<=n;++i){
            ans = max(ans, P[i] - tmp);
            tmp = min(tmp, P[i]);
        }
        return ans;
    }
};

54, Spiral Matrix

Question: Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order. For example, Given the following matrix:
[
 [ 1, 2, 3 ],
 [ 4, 5, 6 ],
 [ 7, 8, 9 ]
]
You should return [1,2,3,6,9,8,7,4,5].
Idea: figure out which direction to go at each position:
class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        if(matrix.empty() || matrix[0].empty()) return vector<int>();
        int m = matrix.size(), n = matrix[0].size();
        vector<int> ans(m*n);
        for(int i=0,j=0,k=0;k<m*n;k++){
            ans[k] = matrix[i][j];
            if(i<(m+1)/2 && i<=(j+1) && i<n-j-1) ++j;
            else if(j>=n/2 && n-j-1<=i && n-j-1<m-i-1) ++i;
            else if(i>=(m+1)/2 && m-i-1<=n-j-1 && m-i-1<j) --j;
            else --i;
        }
        return ans;
    }
};

55, Jump Game

Question: Given an array of non-negative integers, you are initially positioned at the first index of the array. Each element in the array represents your maximum jump length at that position. Determine if you are able to reach the last index.
Idea: The same as the previous version, i.e. using greedy,
class Solution {
public:
    bool canJump(vector<int>& nums) {
        int n = nums.size();
        if(n<=1) return true;
        for(int i=0,j=nums[0];j<n-1;++i){
            j = max(j,i+nums[i]);
            if(i==j) return false;     //### 这个顺序很,别犯低级错误
        }
        return true;
    }
};

56, Merge Intervals

Question: Given a collection of intervals, merge all overlapping intervals.
Idea: sort and find ending points:
/**
 * Definition for an interval.
 * struct Interval {
 *     int start;
 *     int end;
 *     Interval() : start(0), end(0) {}
 *     Interval(int s, int e) : start(s), end(e) {}
 * };
 */
class Solution {
    static bool cmp(const Interval &x, const Interval &y) { 
        if(x.start == y.start) return x.end < y.end;
        return x.start < y.start;
    }
    class less{
        public:
        bool operator ()(const Interval &x, const Interval &y) const { 
            if(x.start == y.start) return x.end < y.end;
            return x.start < y.start;
        }
    };
public:
    vector<Interval> merge(vector<Interval>& intervals) {
        vector<Interval> ans;
        if(intervals.empty()) return ans;
        //sort(intervals.begin(),intervals.end(),cmp);
        sort(intervals.begin(),intervals.end(),less());
        int s = INT_MIN, e = INT_MIN;
        for(int i=0;i<intervals.size();++i){
            if(intervals[i].start <= e) e = max(e, intervals[i].end);
            else{
                if(i) ans.push_back(Interval(s,e));
                s = intervals[i].start;
                e = intervals[i].end;
            }
        }
        ans.push_back(Interval(s,e));
        return ans;
    }
};

57, Insert Interval

Question: Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessary). You may assume that the intervals were initially sorted according to their start times.
Idea: Find 3 groups: 1, before; 2, coupled; 3, after:
/**
 * Definition for an interval.
 * struct Interval {
 *     int start;
 *     int end;
 *     Interval() : start(0), end(0) {}
 *     Interval(int s, int e) : start(s), end(e) {}
 * };
 */
class Solution {
public:
    vector<Interval> insert(vector<Interval>& intervals, Interval newInterval) {
        vector<Interval> ans;
        int s = newInterval.start, e = newInterval.end, i = 0, n = intervals.size();
        while(i<n && intervals[i].end < s) ans.push_back(intervals[i++]);
        while(i<n && intervals[i].start<= e){
            s = min(s,intervals[i].start);
            e = max(e,intervals[i++].end);
        }
        ans.push_back(Interval(s,e));
        while(i<n) ans.push_back(intervals[i++]);
        return ans;
    }
};

58, Length of Last Word

Question: Given a string s consists of upper/lower-case alphabets and empty space characters ' ', return the length of last word in the string.
Idea: Easy string manipulation
class Solution {
public:
    int lengthOfLastWord(string s) {
        s = s.substr(0,s.find_last_not_of(" ")+1);
        return s.size() - 1 - s.find_last_of(" ");
    }
};

59, Spiral Matrix II

Question: Given an integer n, generate a square matrix filled with elements from 1 to n^2 in spiral order. For example, Given n = 3, You should return the following matrix:
[
 [ 1, 2, 3 ],
 [ 8, 9, 4 ],
 [ 7, 6, 5 ]
]
Idea: The same as Spiral Matrix I
class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> ans(n,vector<int>(n));
        for(int i=0,j=0,k=1;k<=n*n;++k){
            ans[i][j] = k;
            if(i<(n+1)/2 && i<=j+1 && i<n-j-1) ++j;
            else if(j>=n/2 && n-j-1<=i && n-j-1<n-i-1) ++i;
            else if(i>=(n+1)/2 && n-i-1<=n-j-1 && n-i-1<j) --j;
            else --i;
        }
        return ans;
    }
};

60, Permutation Sequence

Question: The set [1,2,3,…,n] contains a total of n! unique permutations. By listing and labeling all of the permutations in order, We get the following sequence (ie, for n = 3):
"123"
"132"
"213"
"231"
"312"
"321"
Given n and k, return the kth permutation sequence.
Idea: Residue count (every time divided by (l-1)!)
class Solution {
    const string Str = "123456789";
    vector<int> fac;
public:
    string getPermutation(int n, int k) {
        fac = vector<int>(n,1);
        string ans = Str.substr(0,n);
        --k;
        for(int i=2;i<n;++i) fac[i] = i*fac[i-1];
        for(int i=0;i<n;++i){
            if(!k) return ans;
            int m = k/fac[n-i-1];
            if(m){
                char c = ans[i+m];
                for(int j=m-1;j>=0;--j) ans[i+j+1] = ans[i+j];
                ans[i] = c;
            }
            k %= fac[n-i-1];
        }
        return ans;
    }
};