Weekly Contest 139
1071. Greatest Common Divisor of Strings
For strings
S
andT
, we say "T
dividesS
" if and only ifS = T + ... + T
(T
concatenated with itself 1 or more times)Return the largest string
X
such thatX
divides str1 andX
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 <= str1.length <= 1000
1 <= str2.length <= 1000
str1[i]
andstr2[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 <= matrix.length <= 300
1 <= matrix[i].length <= 300
- All
matrix[i].length
's are equalmatrix[i][j]
is0
or1
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
andarr2
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 numberarr
in array format is also guaranteed to have no leading zeros: eitherarr == [0]
orarr[0] == 1
.Return the result of adding
arr1
andarr2
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 <= arr1.length <= 1000
1 <= arr2.length <= 1000
arr1
andarr2
have no leading zerosarr1[i]
is0
or1
arr2[i]
is0
or1
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 atarget
, return the number of non-empty submatrices that sum to target.A submatrix
x1, y1, x2, y2
is the set of all cellsmatrix[x][y]
withx1 <= x <= x2
andy1 <= 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, ifx1 != 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 <= matrix.length <= 300
1 <= matrix[0].length <= 300
-1000 <= matrix[i] <= 1000
-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.