Weekly Contest 139

1071. Greatest Common Divisor of Strings

For strings S and T, we say "T divides S" if and only if S = T + ... + T  (T concatenated with itself 1 or more times)

Return the largest string X such that X divides str1 and X divides str2.

 

Example 1:

Input: str1 = "ABCABC", str2 = "ABC"
Output: "ABC"

Example 2:

Input: str1 = "ABABAB", str2 = "ABAB"
Output: "AB"

Example 3:

Input: str1 = "LEET", str2 = "CODE"
Output: ""

 

Note:

  1. 1 <= str1.length <= 1000
  2. 1 <= str2.length <= 1000
  3. str1[i] and str2[i] are English uppercase letters.

 

Approach #1: Simulate. [Java]

class Solution {
    public String gcdOfStrings(String str1, String str2) {
        int len1 = str1.length(), len2 = str2.length();
        int minLen = Math.min(str1.length(), str2.length());
        while (minLen > 0) {
            if (len1 % minLen == 0 && len2 % minLen == 0) {
                String subStr = str2.substring(0, minLen);
                if (isRepeat(str1, subStr) && isRepeat(str2, subStr)) {
                    return subStr;
                }
            }
            minLen--;
        }
        return new String("");
    }
    
    public boolean isRepeat(String target, String subStr) {
        int n = subStr.length();
        for (int i = 0; i < target.length(); ++i) {
            if (target.charAt(i) != subStr.charAt(i%n))
                return false;
        }
        return true;
    }
}

  

Analysis:

The greatest common divisor of string's length must is the divisor of str1.length() and str2.length(). So we can find the min length of str1.length() and str2.length() as the common divisor of string's length at the first. If divisor string's length is the divisor of str1.length and str2.length, and str1, str2 are consituted by repeating divisor string, we return the longest divisor string.

 

1072. Flip Columns For Maximum Number of Equal Rows

Given a matrix consisting of 0s and 1s, we may choose any number of columns in the matrix and flip every cell in that column.  Flipping a cell changes the value of that cell from 0 to 1 or from 1 to 0.

Return the maximum number of rows that have all values equal after some number of flips.

 

Example 1:

Input: [[0,1],[1,1]]
Output: 1
Explanation: After flipping no values, 1 row has all values equal.

Example 2:

Input: [[0,1],[1,0]]
Output: 2
Explanation: After flipping values in the first column, both rows have equal values.

Example 3:

Input: [[0,0,0],[0,0,1],[1,1,0]]
Output: 2
Explanation: After flipping values in the first two columns, the last two rows have equal values.

 

Note:

  1. 1 <= matrix.length <= 300
  2. 1 <= matrix[i].length <= 300
  3. All matrix[i].length's are equal
  4. matrix[i][j] is 0 or 1

 

Approach #1: 

class Solution {
    public int maxEqualRowsAfterFlips(int[][] matrix) {
        Map<String, Integer> map = new HashMap<>();
        for (int i = 0; i < matrix.length; ++i) {
            String key = Arrays.toString(matrix[i]);
            for (int j = 0; j < matrix[i].length; ++j) matrix[i][j] ^= 1;
            String rev = Arrays.toString(matrix[i]);
            map.put(key, map.getOrDefault(key, 0) + 1);
            map.put(rev, map.getOrDefault(rev, 0) + 1);
        }
        int ret = -1;
        for (String key : map.keySet()) {
            ret = Math.max(ret, map.get(key));
        }
        
        return ret;
    }
}

  

Analysis:

Intuitively, if two rows have the same numbers or have reverse numbers(0->1 or 1->0), we can flip some column to make them only contains 0 or 1. So we can use a map, the row number to a string as the key and the count as the value, otherwise, we should reverse the  row's numbers as the key, too.

Finally, find the max value in the map.

 

1073. Adding Two Negabinary Numbers

Given two numbers arr1 and arr2 in base -2, return the result of adding them together.

Each number is given in array format:  as an array of 0s and 1s, from most significant bit to least significant bit.  For example, arr = [1,1,0,1] represents the number (-2)^3 + (-2)^2 + (-2)^0 = -3.  A number arr in array format is also guaranteed to have no leading zeros: either arr == [0] or arr[0] == 1.

Return the result of adding arr1 and arr2 in the same format: as an array of 0s and 1s with no leading zeros.

 

Example 1:

Input: arr1 = [1,1,1,1,1], arr2 = [1,0,1]
Output: [1,0,0,0,0]
Explanation: arr1 represents 11, arr2 represents 5, the output represents 16.

 

Note:

  1. 1 <= arr1.length <= 1000
  2. 1 <= arr2.length <= 1000
  3. arr1 and arr2 have no leading zeros
  4. arr1[i] is 0 or 1
  5. arr2[i] is 0 or 1

 

Approach #1: 

class Solution {
    public int[] addNegabinary(int[] arr1, int[] arr2) {
        int i = arr1.length - 1, j = arr2.length - 1, carry = 0;
        Stack<Integer> stack = new Stack<>();
        while (i >= 0 || j >= 0 || carry != 0) {
            int n1 = i >= 0 ? arr1[i--] : 0;
            int n2 = j >= 0 ? arr2[j--] : 0;
            carry = n1 + n2 + carry;
            stack.push(carry & 1);
            carry = -(carry >> 1);
        }
        while (!stack.empty() && stack.peek() == 0) stack.pop();
        int[] ret = new int[stack.size()];
        int index = 0;
        while (!stack.empty()) {
            ret[index++] = stack.pop();
        }
        return ret.length == 0 ? new int[1] : ret;
    }
}

  

Approach #2: [WA]

class Solution {
    public int[] addNegabinary(int[] arr1, int[] arr2) {
        int num1 = 0, num2 = 0;
        int len1 = arr1.length - 1, len2 = arr2.length - 1;
        for (int i = 0; i < arr1.length; ++i) {
            if (arr1[i] == 1) {
                num1 += Math.pow(-2, len1);
                len1--;
            } else {
                len1--;
            } 
        }
        for (int i = 0; i < arr2.length; ++i) {
            if (arr2[i] == 1) {
                num2 += Math.pow(-2, len2);
                len2--;
            } else {
                len2--;
            } 
        }
        int sum = num1 + num2;
        List<Integer> list = new ArrayList<Integer>();
        if (sum == 0) list.add(0);
        while (sum != 0) {
            int remainder = sum % (-2);
            sum = sum / (-2);
            // System.out.println(remainder + " " + sum);
            if (remainder < 0) {
                remainder += 2;
                sum += 1;
            }
            list.add(remainder);
        }
        Collections.reverse(list);
        
        int[] ret = new int[list.size()];
        for (int i = 0; i < list.size(); ++i)
            ret[i] = list.get(i);
        
        return ret;
    }
}

  

1074. Number of Submatrices That Sum to Target

Given a matrix, and a target, return the number of non-empty submatrices that sum to target.

A submatrix x1, y1, x2, y2 is the set of all cells matrix[x][y] with x1 <= x <= x2 and y1 <= y <= y2.

Two submatrices (x1, y1, x2, y2) and (x1', y1', x2', y2') are different if they have some coordinate that is different: for example, if x1 != x1'.

 

Example 1:

Input: matrix = [[0,1,0],[1,1,1],[0,1,0]], target = 0
Output: 4
Explanation: The four 1x1 submatrices that only contain 0.

Example 2:

Input: matrix = [[1,-1],[-1,1]], target = 0
Output: 5
Explanation: The two 1x2 submatrices, plus the two 2x1 submatrices, plus the 2x2 submatrix.

 

Note:

  1. 1 <= matrix.length <= 300
  2. 1 <= matrix[0].length <= 300
  3. -1000 <= matrix[i] <= 1000
  4. -10^8 <= target <= 10^8

 

Approach #1:

class Solution {
    public int numSubmatrixSumTarget(int[][] matrix, int target) {
        int row = matrix.length, col = matrix[0].length;
        int[][] sumMatrix = new int[row+1][col+1];
        sumMatrix[1][1] = matrix[0][0];
        for (int i = 2; i <= row; ++i)
            sumMatrix[i][1] = matrix[i-1][0] + sumMatrix[i-1][1];
        for (int j = 2; j <= col; ++j)
            sumMatrix[1][j] = matrix[0][j-1] + sumMatrix[1][j-1];
        for (int i = 2; i <= row; ++i) {
            for (int j = 2; j <= col; ++j) {
                sumMatrix[i][j] = sumMatrix[i][j-1] + sumMatrix[i-1][j] - sumMatrix[i-1][j-1] + matrix[i-1][j-1];
                
            }
        }
        
        int count = 0;
        for (int i = 1; i <= row; i++) {
            for (int j = 1; j <= col; ++j) {
                count += countTarget(i, j, target, sumMatrix);
            }
        }
        
        return count;
    }
    
    public int countTarget(int x, int y, int target, int[][] sumMatrix) {
        int subCount = 0, sum = 0;
        for (int i = 0; i < x; ++i) {
            for (int j = 0; j < y; ++j) {
                sum = sumMatrix[x][y] - sumMatrix[i][y] - sumMatrix[x][j] + sumMatrix[i][j];
                if (sum == target) subCount++;
            }
        }
        return subCount;
    }
}

  

Analysis:

Firstly, we calculate the sum of a sub-matrix from [0, 0] to [i, j].

Secondly, traveling all the points in the sub-matrix as the start point and claculate the sum, if the sum equal to the target, the count number increase one.

 

posted @ 2019-06-02 16:33  Veritas_des_Liberty  阅读(324)  评论(0编辑  收藏  举报