zoukankan      html  css  js  c++  java
  • 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.

    永远渴望,大智若愚(stay hungry, stay foolish)
  • 相关阅读:
    两数之和
    数组,链表,跳表
    第二讲:增长全景图
    三数之和
    第一讲:增长的本质
    移动零
    八十忆双亲+师友杂记
    java:从命令行接收多个数字,求和之后输出结果
    编程的精义读后感
    java语言基础第三讲作业
  • 原文地址:https://www.cnblogs.com/h-hkai/p/10963330.html
Copyright © 2011-2022 走看看