Tuesday, November 24, 2020

LeetCode [459] Repeated Substring Pattern

459. Repeated Substring Pattern
Easy

Given a non-empty string check if it can be constructed by taking a substring of it and appending multiple copies of the substring together. You may assume the given string consists of lowercase English letters only and its length will not exceed 10000.

 

Example 1:

Input: "abab"
Output: True
Explanation: It's the substring "ab" twice.

Example 2:

Input: "aba"
Output: False

Example 3:

Input: "abcabcabcabc"
Output: True
Explanation: It's the substring "abc" four times. (And the substring "abcabc" twice.)


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
class Solution {
    public boolean repeatedSubstringPattern(String s) {
        int n = s.length(), i = 1;
        int[] dp = new int[n];
        while(i<n){
            int l = dp[i-1];
            while(l>0 && s.charAt(i)!=s.charAt(l)){
                l = dp[l-1];
            }
            if(s.charAt(i)==s.charAt(l)){
                dp[i] = l+1;
            }
            i++;
        }
        if(dp[n-1]==0) return false;
        int lenRepeat = n-dp[n-1];
        return n%lenRepeat==0;
    }
}

YMSF

abcabc 3 pattern是abc, 整个str可以repeat ,返回true

abababab 4 pattern是abab,整个str可以repeat, 返回 true

abcabc 2 pattern是ab,整个str不能repeat, 返回false

写完后要求不用extra memory ,然后问如何求出最长的repeat pattern, 讲了brute force,从大到小,要求优化,发现试common denominator 的长度即可,但面试官说不是最优解

 

至少重复出现两次

 


Monday, November 23, 2020

LeetCode [702] Search in a Sorted Array of Unknown Size

 702. Search in a Sorted Array of Unknown Size

Medium

Given an integer array sorted in ascending order, write a function to search target in nums.  If target exists, then return its index, otherwise return -1However, the array size is unknown to you. You may only access the array using an ArrayReader interface, where ArrayReader.get(k) returns the element of the array at index k (0-indexed).

You may assume all integers in the array are less than 10000, and if you access the array out of bounds, ArrayReader.get will return 2147483647.

 

Example 1:

Input: array = [-1,0,3,5,9,12], target = 9
Output: 4
Explanation: 9 exists in nums and its index is 4

Example 2:

Input: array = [-1,0,3,5,9,12], target = 2
Output: -1
Explanation: 2 does not exist in nums so return -1

 

Constraints:

  • You may assume that all elements in the array are unique.
  • The value of each element in the array will be in the range [-9999, 9999].
  • The length of the array will be in the range [1, 10^4].
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/**
 * // This is ArrayReader's API interface.
 * // You should not implement it, or speculate about its implementation
 * interface ArrayReader {
 *     public int get(int index) {}
 * }
 */

class Solution {
    int N = 10000;
    int M = 2147483647;
    public int search(ArrayReader reader, int target) {
        int l = 0, r = N;
        while(l<=r){
            int m = (l+r)/2;
            int res = reader.get(m);
            if(res==M){
                r = m-1;
            }else{
                if(res==target){
                    return m;
                }
                if(res<target){
                    l = m+1;
                }else{
                    r = m-1;
                }
            }
        }
        return -1;
    }
}

第四轮是面coding,有个indefinitely long list of words A,你不能直接access,只能call A.get(i)来得到第i个word,word是sorted,要查找一个word,返回在list里的index,followup是要你写一个A这样的object用来测试你的code,最后的followup是,我用了2^n的增速在寻找index的上边界,再binary search上下边界之间的word,小哥问有没有更快的算法,其实是问有没有比2^n增速更快的a^n的a能使整体time complexity更低


我的做法是写一个class,一个variablelist of word,一个function get,如果get输入大于等于list的长度,返回一个无穷大,跟任何str比都要大,如果输入在范围内,返回word

Saturday, November 21, 2020

LeetCode [1273] Delete Tree Nodes

 1273. Delete Tree Nodes

Medium

A tree rooted at node 0 is given as follows:

  • The number of nodes is nodes;
  • The value of the i-th node is value[i];
  • The parent of the i-th node is parent[i].

Remove every subtree whose sum of values of nodes is zero.

After doing so, return the number of nodes remaining in the tree.

 

Example 1:

Input: nodes = 7, parent = [-1,0,0,1,2,2,2], value = [1,-2,4,0,-2,-1,-1]
Output: 2

Example 2:

Input: nodes = 7, parent = [-1,0,0,1,2,2,2], value = [1,-2,4,0,-2,-1,-2]
Output: 6

Example 3:

Input: nodes = 5, parent = [-1,0,1,0,0], value = [-672,441,18,728,378]
Output: 5

Example 4:

Input: nodes = 5, parent = [-1,0,0,1,1], value = [-686,-842,616,-739,-746]
Output: 5

 

Constraints:

  • 1 <= nodes <= 10^4
  • parent.length == nodes
  • 0 <= parent[i] <= nodes - 1
  • parent[0] == -1 which indicates that 0 is the root.
  • value.length == nodes
  • -10^5 <= value[i] <= 10^5
  • The given input is guaranteed to represent a valid tree.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Solution {
    public int deleteTreeNodes(int n, int[] parent, int[] value) {
        List<List<Integer>> graph = new ArrayList<>(n); // Create graph for the tree
        for (int i = 0; i < n; i++) graph.add(new ArrayList<>());
        for (int i = 0; i < n; i++) {
            if (parent[i] != -1) {
                graph.get(parent[i]).add(i);
            }
        }
        return dfs(graph, value, 0)[1];
    }

    private int[] dfs(List<List<Integer>> graph, int[] value, int root) {
        int sum = value[root];
        int cntRemainNodes = 1;
        for (int child : graph.get(root)) {
            int[] temp = dfs(graph, value, child);
            sum += temp[0];
            cntRemainNodes += temp[1];
        }
        if (sum == 0) cntRemainNodes = 0; // Don't count nodes of this subtree
        return new int[]{sum, cntRemainNodes};
    }
}

Friday, November 20, 2020

LeetCode [427] Construct Quad Tree

 427. Construct Quad Tree

Medium

Given a n * n matrix grid of 0's and 1's only. We want to represent the grid with a Quad-Tree.

Return the root of the Quad-Tree representing the grid.

Notice that you can assign the value of a node to True or False when isLeaf is False, and both are accepted in the answer.

A Quad-Tree is a tree data structure in which each internal node has exactly four children. Besides, each node has two attributes:

  • val: True if the node represents a grid of 1's or False if the node represents a grid of 0's. 
  • isLeaf: True if the node is leaf node on the tree or False if the node has the four children.
class Node {
    public boolean val;
    public boolean isLeaf;
    public Node topLeft;
    public Node topRight;
    public Node bottomLeft;
    public Node bottomRight;
}

We can construct a Quad-Tree from a two-dimensional area using the following steps:

  1. If the current grid has the same value (i.e all 1's or all 0's) set isLeaf True and set val to the value of the grid and set the four children to Null and stop.
  2. If the current grid has different values, set isLeaf to False and set val to any value and divide the current grid into four sub-grids as shown in the photo.
  3. Recurse for each of the children with the proper sub-grid.

If you want to know more about the Quad-Tree, you can refer to the wiki.

Quad-Tree format:

The output represents the serialized format of a Quad-Tree using level order traversal, where null signifies a path terminator where no node exists below.

It is very similar to the serialization of the binary tree. The only difference is that the node is represented as a list [isLeaf, val].

If the value of isLeaf or val is True we represent it as 1 in the list [isLeaf, val] and if the value of isLeaf or val is False we represent it as 0.

 

Example 1:

Input: grid = [[0,1],[1,0]]
Output: [[0,1],[1,0],[1,1],[1,1],[1,0]]
Explanation: The explanation of this example is shown below:
Notice that 0 represnts False and 1 represents True in the photo representing the Quad-Tree.

Example 2:

Input: grid = [[1,1,1,1,0,0,0,0],[1,1,1,1,0,0,0,0],[1,1,1,1,1,1,1,1],[1,1,1,1,1,1,1,1],[1,1,1,1,0,0,0,0],[1,1,1,1,0,0,0,0],[1,1,1,1,0,0,0,0],[1,1,1,1,0,0,0,0]]
Output: [[0,1],[1,1],[0,1],[1,1],[1,0],null,null,null,null,[1,0],[1,0],[1,1],[1,1]]
Explanation: All values in the grid are not the same. We divide the grid into four sub-grids.
The topLeft, bottomLeft and bottomRight each has the same value.
The topRight have different values so we divide it into 4 sub-grids where each has the same value.
Explanation is shown in the photo below:

Example 3:

Input: grid = [[1,1],[1,1]]
Output: [[1,1]]

Example 4:

Input: grid = [[0]]
Output: [[1,0]]

Example 5:

Input: grid = [[1,1,0,0],[1,1,0,0],[0,0,1,1],[0,0,1,1]]
Output: [[0,1],[1,1],[1,0],[1,0],[1,1]]

 

Constraints:

  • n == grid.length == grid[i].length
  • n == 2^x where 0 <= x <= 6
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/*
// Definition for a QuadTree node.
class Node {
    public boolean val;
    public boolean isLeaf;
    public Node topLeft;
    public Node topRight;
    public Node bottomLeft;
    public Node bottomRight;

    
    public Node() {
        this.val = false;
        this.isLeaf = false;
        this.topLeft = null;
        this.topRight = null;
        this.bottomLeft = null;
        this.bottomRight = null;
    }
    
    public Node(boolean val, boolean isLeaf) {
        this.val = val;
        this.isLeaf = isLeaf;
        this.topLeft = null;
        this.topRight = null;
        this.bottomLeft = null;
        this.bottomRight = null;
    }
    
    public Node(boolean val, boolean isLeaf, Node topLeft, Node topRight, Node bottomLeft, Node bottomRight) {
        this.val = val;
        this.isLeaf = isLeaf;
        this.topLeft = topLeft;
        this.topRight = topRight;
        this.bottomLeft = bottomLeft;
        this.bottomRight = bottomRight;
    }
};
*/

class Solution {
    public Node construct(int[][] grid) {
        return helper(grid, 0, 0, grid.length);
    }
    private Node helper(int[][] grid, int x, int y, int len) {
        if (len == 1) {
            return new Node(grid[x][y] != 0, true, null, null, null, null);
        }
        Node result = new Node();
        Node topLeft = helper(grid, x, y, len / 2);
        Node topRight = helper(grid, x, y + len / 2, len / 2);
        Node bottomLeft = helper(grid, x + len / 2, y, len / 2);
        Node bottomRight = helper(grid, x + len / 2, y + len / 2, len / 2);
        if (topLeft.isLeaf && topRight.isLeaf && bottomLeft.isLeaf && bottomRight.isLeaf
           && topLeft.val == topRight.val && topRight.val == bottomLeft.val && bottomLeft.val == bottomRight.val) {
            result.isLeaf = true;
            result.val = topLeft.val;
        } else {
            result.topLeft = topLeft;
            result.topRight = topRight;
            result.bottomLeft = bottomLeft;
            result.bottomRight = bottomRight;
        }
        return result;
    }
}

Friday, November 13, 2020

LeetCode [1120] Maximum Average Subtree

1120. Maximum Average Subtree
Medium

Given the root of a binary tree, find the maximum average value of any subtree of that tree.

(A subtree of a tree is any node of that tree plus all its descendants. The average value of a tree is the sum of its values, divided by the number of nodes.)

 

Example 1:

Input: [5,6,1]
Output: 6.00000
Explanation: 
For the node with value = 5 we have an average of (5 + 6 + 1) / 3 = 4.
For the node with value = 6 we have an average of 6 / 1 = 6.
For the node with value = 1 we have an average of 1 / 1 = 1.
So the answer is 6 which is the maximum.

 

Note:

  1. The number of nodes in the tree is between 1 and 5000.
  2. Each node will have a value between 0 and 100000.
  3. Answers will be accepted as correct if they are within 10^-5 of the correct answer.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    double maxAverage = Integer.MIN_VALUE;
    public double maximumAverageSubtree(TreeNode root) {
        helper(root);
        return maxAverage;
    }
    
    
    //sum, count
    double[] helper(TreeNode node){
        if(node==null) return new double[0];
        double sum = node.val, count = 1;
        if(node.left!=null){
            double[] left = helper(node.left);
            sum += left[0];
            count += left[1];
        }
        
        if(node.right!=null){
            double[] right = helper(node.right);
            sum += right[0];
            count += right[1];
        }

        maxAverage = Math.max(maxAverage, sum/count);
        return new double[]{sum, count};
    }
}