weekly contest 115

958. Check Completeness of a Binary Tree

Given a binary tree, determine if it is a complete binary tree.

Definition of a complete binary tree from Wikipedia:
In a complete binary tree every level, except possibly the last, is completely filled, and all nodes in the last level are as far left as possible. It can have between 1 and 2h nodes inclusive at the last level h.

 

Example 1:

Input: [1,2,3,4,5,6]
Output: true
Explanation: Every level before the last is full (ie. levels with node-values {1} and {2, 3}), and all nodes in the last level ({4, 5, 6}) are as far left as possible.

Example 2:

Input: [1,2,3,4,5,null,7]
Output: false
Explanation: The node with value 7 isn't as far left as possible.
 

Note:

  1. The tree will have between 1 and 100 nodes.

Approach #1: C++.

/**
 * 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:
    bool isCompleteTree(TreeNode* root) {
        queue<TreeNode*> nodes;
        nodes.push(root);
        while (true) {
            TreeNode* cur = nodes.front();
            if (cur == NULL) break;
            nodes.push(cur->left);
            nodes.push(cur->right);
            nodes.pop();
        }
        while (!nodes.empty()) {
            TreeNode* cur = nodes.front(); 
            if (cur != NULL) return false;
            nodes.pop();
        }
        return true;
    }
};

  

957. Prison Cells After N Days

There are 8 prison cells in a row, and each cell is either occupied or vacant.

Each day, whether the cell is occupied or vacant changes according to the following rules:

  • If a cell has two adjacent neighbors that are both occupied or both vacant, then the cell becomes occupied.
  • Otherwise, it becomes vacant.

(Note that because the prison is a row, the first and the last cells in the row can't have two adjacent neighbors.)

We describe the current state of the prison in the following way: cells[i] == 1 if the i-th cell is occupied, else cells[i] == 0.

Given the initial state of the prison, return the state of the prison after N days (and N such changes described above.)

 

 

Example 1:

Input: cells = [0,1,0,1,1,0,0,1], N = 7
Output: [0,0,1,1,0,0,0,0]
Explanation: 
The following table summarizes the state of the prison on each day:
Day 0: [0, 1, 0, 1, 1, 0, 0, 1]
Day 1: [0, 1, 1, 0, 0, 0, 0, 0]
Day 2: [0, 0, 0, 0, 1, 1, 1, 0]
Day 3: [0, 1, 1, 0, 0, 1, 0, 0]
Day 4: [0, 0, 0, 0, 0, 1, 0, 0]
Day 5: [0, 1, 1, 1, 0, 1, 0, 0]
Day 6: [0, 0, 1, 0, 1, 1, 0, 0]
Day 7: [0, 0, 1, 1, 0, 0, 0, 0]

Example 2:

Input: cells = [1,0,0,1,0,0,1,0], N = 1000000000
Output: [0,0,1,1,1,1,1,0]

 

Note:

  1. cells.length == 8
  2. cells[i] is in {0, 1}
  3. 1 <= N <= 10^9

Appraoch #1: C++.

class Solution {
public:
    vector<int> prisonAfterNDays(vector<int>& cells, int N) {
        unordered_map<string, int> seen;
        while (N > 0) {
            string temp(cells.begin(), cells.end());
            seen[temp] = N--;
            vector<int> dummy(8, 0);
            for (int j = 1; j < 7; ++j) 
                dummy[j] = cells[j-1] == cells[j+1] ? 1 : 0;
            cells = dummy;
            string ant(cells.begin(), cells.end());
            if (seen.count(ant)) 
                N %= seen[ant] - N;
        }
        return cells;
    }
};

  

Analysis:

There are only six binary numbers,  so all of the difference possibilities is 2^6. 

so we can use a map to store the case, if N is very large we can reduce the number of calculation by 

N %= seen[ant] - N;

 

959. Regions Cut By Slashes

In a N x N grid composed of 1 x 1 squares, each 1 x 1 square consists of a /\, or blank space.  These characters divide the square into contiguous regions.

(Note that backslash characters are escaped, so a \ is represented as "\\".)

Return the number of regions.

 

 

Example 1:

Input:
[
  " /",
  "/ "
]
Output: 2
Explanation: The 2x2 grid is as follows:

Example 2:

Input:
[
  " /",
  "  "
]
Output: 1
Explanation: The 2x2 grid is as follows:

Example 3:

Input:
[
  "\\/",
  "/\\"
]
Output: 4
Explanation: (Recall that because \ characters are escaped, "\\/" refers to \/, and "/\\" refers to /\.)
The 2x2 grid is as follows:

Example 4:

Input:
[
  "/\\",
  "\\/"
]
Output: 5
Explanation: (Recall that because \ characters are escaped, "/\\" refers to /\, and "\\/" refers to \/.)
The 2x2 grid is as follows:

Example 5:

Input:
[
  "//",
  "/ "
]
Output: 3
Explanation: The 2x2 grid is as follows:

 

Note:

  1. 1 <= grid.length == grid[0].length <= 30
  2. grid[i][j] is either '/''\', or ' '.

 

Approach #1: C++. [Union Find]

class Solution {
public:
    int regionsBySlashes(vector<string>& grid) {
        n = grid.size();
        count = n*n*4;
        f.resize(n*n*4);
        
        for (int i = 0; i < n*n*4; ++i) f[i] = i;
        
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < n; ++j) {
                if (i > 0) _union(g(i-1, j, 2), g(i, j, 0));
                if (j > 0) _union(g(i, j-1, 1), g(i, j, 3));
                if (grid[i][j] != '/') {
                    _union(g(i, j, 0), g(i, j, 1));
                    _union(g(i, j, 2), g(i, j, 3));
                }
                if (grid[i][j] != '\\') {
                    _union(g(i, j, 0), g(i, j, 3));
                    _union(g(i, j, 1), g(i, j, 2));
                }
            }
        }
        
        return count;
    }

private:
    int count, n;
    vector<int> f;
    
    int find(int x) {
        if (x != f[x]) {
            f[x] = find(f[x]);
        }
        return f[x];
    }
    
    void _union(int x, int y) {
        x = find(x);
        y = find(y);
        
        if (x != y) {
            f[x] = y;
            count--;
        }
    }
    
    int g(int i, int j, int k) {
        return (i*n + j) * 4 + k;
    }
};

 

Analysis:

@lee215

In this problem we split the ceil with 4 subceils (like tihs). if the subceils are connected then we draw with the same color. the subceils use the number of (i*n + j) * 4 + k represented and using union-find to find the connected ceils. If two ceils are connected we should

--cout.

 

960. Delete Columns to Make Sorted III

We are given an array A of N lowercase letter strings, all of the same length.

Now, we may choose any set of deletion indices, and for each string, we delete all the characters in those indices.

For example, if we have an array A = ["babca","bbazb"] and deletion indices {0, 1, 4}, then the final array after deletions is ["bc","az"].

Suppose we chose a set of deletion indices D such that after deletions, the final array has every element (row) in lexicographic order.

For clarity, A[0] is in lexicographic order (ie. A[0][0] <= A[0][1] <= ... <= A[0][A[0].length - 1]), A[1] is in lexicographic order (ie. A[1][0] <= A[1][1] <= ... <= A[1][A[1].length - 1]), and so on.

Return the minimum possible value of D.length.

 

Example 1:

Input: ["babca","bbazb"]
Output: 3
Explanation: After deleting columns 0, 1, and 4, the final array is A = ["bc", "az"].
Both these rows are individually in lexicographic order (ie. A[0][0] <= A[0][1] and A[1][0] <= A[1][1]).
Note that A[0] > A[1] - the array A isn't necessarily in lexicographic order.

Example 2:

Input: ["edcba"]
Output: 4
Explanation: If we delete less than 4 columns, the only row won't be lexicographically sorted.

Example 3:

Input: ["ghi","def","abc"]
Output: 0
Explanation: All rows are already lexicographically sorted.

 

Note:

  1. 1 <= A.length <= 100
  2. 1 <= A[i].length <= 100

Approach #1: C++. [DP]

class Solution {
public:
    int minDeletionSize(vector<string>& A) {
        int m = A.size(), n = A[0].size();
        int res = INT_MAX;
        
        vector<int> dp(n, 1);
        
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < i; ++j) {
                int good = 1;
                for (int k = 0; k < m; ++k) {
                    if (A[k][j] > A[k][i]) {
                        good = 0;
                        break;
                    }
                }
                if (good == 1) 
                    dp[i] = max(dp[i], dp[j]+1);
            }
            
            res = min(res, n-dp[i]); 
        }
        
        return res;
    }
};

  

Analysis:

We use dp[i] represent the maximum increasing subsequence's length.

dynamic transfer equation: 

dp[i] = max(dp[i], dp[j]+1);

 

posted @ 2018-12-16 12:53  Veritas_des_Liberty  阅读(216)  评论(0编辑  收藏  举报