Technical dry goods (3): LeetCode41-50 detailed questions

41. Missing first positive number

Give you an unsorted array of integers, please find the smallest positive integer that does not appear in it.

Example 1:

输入: [1,2,0]
输出: 3

Example 2:

输入: [3,4,-1,1]
输出: 2

Example 3:

输入: [7,8,9,11,12]
输出: 1

prompt:

The time complexity of your algorithm should be O( n ), and only constant level of extra space can be used.

Hash table method

// 时间复杂度 O(N) 空间复杂度 O(N)
    public int firstMissingPositive(int[] nums) {
        int n = nums.length;
        Set<Integer> set = new HashSet<>();        for(int num : nums) set.add(num);
        for(int i = 1;  i <= n; i ++){
            if(!set.contains(i)) return i;
        }        return n + 1;
    }

Sorting method

// 时间复杂度 O(Nlog(N)) 空
    public int firstMissingPositive(int[] nums) {
        // 先排序 Nlog(N)
        Arrays.sort(nums);        int pre = 0;
        for(int i = 0; i < nums.length; i ++){
            // 跳过非正整数和重复值
            if(nums[i] <= 0 || nums[i] == pre) continue;
            // 找到第一个突变的元素
            else if(nums[i] > pre + 1) break;
            pre ++;        }        return pre + 1;
    }

In-place hashing

Technical dry goods (3): LeetCode41-50 detailed questions

 

// 时间复杂度 O(N) 空间复杂度 O(1)
    // 原地哈希: 自定义哈希函数 将数值 i 映射到 i - 1的位置上
    public int firstMissingPositive(int[] nums) {
        int len = nums.length;
        for(int i = 0; i < len; i ++){
            // 在指定范围内, 且没有放在正确位置上, 交换
            while(nums[i] > 0 && nums[i] <= len && nums[nums[i] - 1] != nums[i]){
                swap(nums, nums[i] - 1, i);
            }        }        // 找到不符合的位置        for(int i = 0; i < len; i ++){
            if(nums[i] != i + 1) return i + 1;
        }        // 都正确则返回数组长度 + 1
        return len + 1;
    }    void swap(int[] nums, int i, int j){
        int temp = nums[i];
        nums[i] = nums[j];        nums[j] = temp;    }

42. catch rain

Given  n  non-negative integers representing the height map of each column with a width of 1, calculate how much rain can be received by the columns arranged in this way after it rains.

Technical dry goods (3): LeetCode41-50 detailed questions

 

The above is the height map represented by the array [0,1,0,2,1,0,1,3,2,1,2,1]. In this case, 6 units of rainwater (blue Part means rain). Thanks to Marcos for  contributing this picture.

Example:

输入: [0,1,0,2,1,0,1,3,2,1,2,1]
输出: 6

Violent solution

// 时间复杂度 O(N^2)
	public int trap(int[] height) {
        int res = 0;
        // 遍历每一列柱子
        for(int i = 1; i < height.length - 1; i ++){
            // 分别记录当前柱子向左 向右的最大高度
            int leftMax = 0, rightMax = 0;
            for(int j = 0; j <= i; j ++) 
                leftMax = Math.max(leftMax, height[j]);            for(int j = i; j < height.length; j ++) 
                rightMax = Math.max(rightMax, height[j]);			// 当前位置 water[i] = min(max(h[0->i], h(i->len-1))) - h[i]
            res += Math.min(leftMax, rightMax) - height[i];        }        return res;
    }

Dynamic programming

// 时间复杂度 优化至 O(N) , 但空间复杂度为 O(N)
	public int trap(int[] height) {
        if(height.length == 0) return 0;
        int n = height.length;
        // 优化方案: 创建两个备忘录,分别记录leftMax 和 rightMax
        int[] leftMax = new int[n];
        int[] rightMax = new int[n];
        int res = 0;
        // 初始化
        leftMax[0] = height[0];
        rightMax[n - 1] = height[n - 1];
        for(int i = 1; i < n; i ++) 
            leftMax[i] = Math.max(height[i], leftMax[i - 1]);
        for(int i = n - 2; i >= 0; i --) 
            rightMax[i] = Math.max(height[i] , rightMax[i + 1]);
        for(int i = 1; i < n - 1; i ++) 
            res += Math.min(leftMax[i], rightMax[i]) - height[i];        return res;
    }

Double pointer

// 时间复杂度 O(N) 空间 O(1)
	// 省去创建备忘录的空间, 边走变算    public int trap(int[] height) {
        if(height.length == 0) return 0;
        int n = height.length;
        int l = 0, r = height.length - 1, res = 0;
        int leftMax = height[0], rightMax = height[n - 1];
        while(l <= r){
            leftMax = Math.max(leftMax, height[l]);            rightMax = Math.max(rightMax, height[r]);            if(leftMax < rightMax) 
                res += leftMax - height[l ++];            else 
                res += rightMax - height[r --];        }        return res;
    }

43. String multiplication

Given two non-negative integers num1 and num2 represented in string form, return the product of num1 and num2, and their product is also represented in string form.

Example 1:

输入: num1 = "2", num2 = "3"
输出: "6"

Example 2:

输入: num1 = "123", num2 = "456"
输出: "56088"

Description:

  1. The length of num1 and num2 is less than 110.
  2. num1 and num2 only contain the numbers 0-9.
  3. Neither num1 nor num2 start with a zero, unless it is the number 0 itself.
  4. You cannot use any large number types of the standard library (such as BigInteger) or directly convert the input to an integer for processing .
/**
num1的第i位(高位从0开始)和num2的第j位相乘的结果在乘积中的位置是[i+j, i+j+1]
例: 123 * 45,  123的第1位 2 和45的第0位 4 乘积 08 存放在结果的第[1, 2]位中
          index:    0 1 2 3 4  
                        1 2 3
                    *     4 5
                    ---------
                          1 5
                        1 0
                      0 5
                    ---------
                      0 6 1 5
                        1 2
                      0 8
                    0 4
                    ---------
                    0 5 5 3 5
这样我们就可以单独都对每一位进行相乘计算把结果存入相应的index中        
**/
public String multiply(String num1, String num2) {
    int m = num1.length(), n = num2.length();
    // 记录每位数字的数组
    int[] arr = new int[m + n];
    // 从个位开始计算
    for(int i = m - 1; i >= 0; i --){
        for(int j = n - 1; j >= 0; j --){
            // i+j, i+j+1
            int mul = (num1.charAt(i) - '0') * (num2.charAt(j) - '0');
            int p1 = i + j, p2 = i + j + 1;
            // 本身乘积 + 原来的数
            int sum = mul + arr[p2];
            // 取个位
            arr[p2] = sum % 10;
            // 进位
            arr[p1] += sum / 10;
        }
    }
    // 移除前导零,只需记录第一个非0的位置即可
    int i = 0;
    while(i < arr.length && arr[i] == 0) i ++;
    if(i == arr.length) return "0";
    StringBuilder res = new StringBuilder();
    while(i < arr.length){
        res.append(arr[i++]);
    }
    return res.toString();
}

44. Wildcard matching

Given a string (s) and a character pattern (p), implement a wildcard matching that supports'?' and'*'.

'?' 可以匹配任何单个字符。
'*' 可以匹配任意字符串(包括空字符串)。

Only when two strings match exactly is a match .

Description:

  • s may be empty and only contain lowercase letters from az.
  • p may be empty and contains only lowercase letters from az, and the characters? and *.

Example 1:

输入:
s = "aa"
p = "a"
输出: false
解释: "a" 无法匹配 "aa" 整个字符串。

Example 2:

输入:
s = "aa"
p = "*"
输出: true
解释: '*' 可以匹配任意字符串。

Example 3:

输入:
s = "cb"
p = "?a"
输出: false
解释: '?' 可以匹配 'c', 但第二个 'a' 无法匹配 'b'。

Example 4:

输入:
s = "adceb"
p = "*a*b"
输出: true
解释: 第一个 '*' 可以匹配空字符串, 第二个 '*' 可以匹配字符串 "dce".

Example 5:

输入:
s = "acdcb"
p = "a*c?b"
输出: false
// f[i][j] = 标识 s的 0 - i 与 p的 0 - j 是否匹配
public boolean isMatch(String s, String p) {    int m = s.length(), n = p.length();    boolean[][] f = new boolean[m + 1][n + 1];
	// 空串匹配    f[0][0] = true;
	// s为空,只要p的开头是* 就代表匹配
    for(int j = 1; j <= n; j ++){
        if(p.charAt(j - 1) == '*') f[0][j] = true;
        else break;    }    for(int i = 1; i <= m; i ++){
        for(int j = 1; j <= n; j ++){
            // f[i][j - 1]的情况 标识 ab和ab*
            // f[i - 1][j]的情况 标识 abcd 和 ab*
            if(p.charAt(j - 1) == '*'){
                f[i][j] = f[i][j - 1] || f[i - 1][j];
            }else if(p.charAt(j - 1) == '?' || s.charAt(i - 1) == p.charAt(j - 1)){
                f[i][j] = f[i - 1][j - 1];
            }
        }
    }
    return f[m][n];
}

45. Jumping Game II

Given an array of non-negative integers, you are initially at the first position of the array.

Each element in the array represents the maximum length you can jump at that position.

Your goal is to use the least number of jumps to reach the last position of the array.

Example:

输入: [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。
     从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。

Description:

Suppose you can always reach the last position of the array.

Technical dry goods (3): LeetCode41-50 detailed questions

 

how are you

public int jump(int[] nums) {
        int ans = 0, start = 0, end = 1;
        while(end < nums.length){
            int maxPos = 0;
            for(int i = l; i < end; i ++){
                //能跳到的最远的距离
                maxPos = Math.max(maxPos, i + nums[i]);
            }
            //下一次起跳点范围开始的格子
            start = end;
            //下一次起跳点范围结束的格子
            end = maxPos + 1;
            ans ++;
        }
        return ans;
    }

46. ​​Full arrangement

Given a   sequence without repeated numbers, return all possible permutations.

Example:

输入: [1,2,3]
输出:[  [1,2,3],
  [1,3,2],
  [2,1,3],
  [2,3,1],
  [3,1,2],
  [3,2,1]
]class Solution {
    List<List<Integer>> res = new ArrayList<>();
    List<Integer> path = new ArrayList<>();
    boolean[] used;    public List<List<Integer>> permute(int[] nums) {
        used = new boolean[nums.length];
        dfs(nums);        return res;
    }    void dfs(int[] nums){
        if(path.size() == nums.length) {
            res.add(new ArrayList<>(path));
            return;
        }        for(int i = 0; i < nums.length; i ++){
            if(!used[i]){
                used[i] = true;
                path.add(nums[i]);
                dfs(nums);                path.remove(path.size() - 1);
                used[i] = false;
            }        }    }}

47. Full Arrangement II

Given a sequence that can contain repeated numbers, return all non-repeating full permutations.

Example:

输入: [1,1,2]
输出:[
  [1,1,2],
  [1,2,1],
  [2,1,1]
]

Technical dry goods (3): LeetCode41-50 detailed questions

 

We need to be clear, where in this DFS process, there are duplicates? In this picture, it is already very obvious:

  • The starting point of this search is the same as the starting point of last time, visited[i-1] == visited[i].
  • And the last count has been cancelled, visited[i-1] == false.

To ensure that i-1 does not cross the boundary, the condition of i>0 is added:

if (i > 0 && nums[i] == nums[i - 1] && !visited[i - 1]) {
    continue;
}List<List<Integer>> res = new ArrayList<>();
    List<Integer> path = new ArrayList<>();
    boolean[] visited;
    public List<List<Integer>> permuteUnique(int[] nums) {
        visited = new boolean[nums.length];
        Arrays.sort(nums); //保证数组的有序性
        dfs(nums);
        return res;
    }
        void dfs(int[]nums){
        if(path.size() == nums.length) {
            res.add(new ArrayList<>(path));
            return;
        }
        for(int i = 0; i < nums.length ; i++){
            if( visited[i]) continue;
            if( i > 0 && nums[i] == nums[i - 1]  && !visited[i - 1]) continue; //此处剪枝
            visited[i] = true;
            path.add(nums[i]);
            dfs(nums);
            visited[i] = false;
            path.remove(path.size()-1);
        }
    }

48. Rotate image

Given an  n  ×  n  two-dimensional matrix represents an image.

Rotate the image 90 degrees clockwise.

Description:

You have to rotate the image in place , which means you need to directly modify the input two-dimensional matrix. Please do not use another matrix to rotate the image.

Example 1:

给定 matrix = 
[  [1,2,3],  [4,5,6],  [7,8,9]],原地旋转输入矩阵,使其变为:[  [7,4,1],  [8,5,2],  [9,6,3]]

Example 2:

给定 matrix =
[  [ 5, 1, 9,11],
  [ 2, 4, 8,10],
  [13, 3, 6, 7],
  [15,14,12,16]
], 原地旋转输入矩阵,使其变为:[  [15,13, 2, 5],
  [14, 3, 4, 1],
  [12, 6, 8, 9],
  [16, 7,10,11]
]public void rotate(int[][] matrix) {
        int n = matrix.length;        //转置        /*
         1 2 3  --> 1 4 7
         4 5 6  --> 2 5 8
         7 8 9  --> 3 6 9
        */
        for(int i = 0; i < n; i ++){
            for(int j = i; j < n; j ++){
                swap(matrix, i, j, j, i);
            }
        }
        /*
         1 4 7  --> 7 4 1
         2 5 8  --> 8 5 2         3 6 9  --> 9 6 3        */        for(int i = 0; i < n; i ++){
            for(int j = 0; j < n / 2; j ++){
                swap(matrix, i, j, i, n - j - 1);
            }
        }
    }
    void swap(int[][] m, int i1, int j1, int i2, int j2){
        int temp = m[i1][j1];
        m[i1][j1] = m[i2][j2];
        m[i2][j2] = temp;
    }

49. Grouping of Letter Alien Words

Given an array of strings, combine letter dyslexia together. Aliphatic words refer to strings with the same letters but different arrangements.

Example:

输入: ["eat", "tea", "tan", "ate", "nat", "bat"]
输出:[
  ["ate","eat","tea"],
  ["nat","tan"],
  ["bat"]
]

Description:

  • All entries are in lowercase letters.
  • The order in which the answers are output is not considered.
public List<List<String>> groupAnagrams(String[] strs) {
        //O(N KlogK) N = strs.length  K = str.length()
        if(strs.length == 0) return new ArrayList<>();
        Map<String, List> hash = new HashMap<>();
        for(String str : strs){
            // 字符排序
            char[] chs = str.toCharArray();            Arrays.sort(chs);            String key = new String(chs);
            if(!hash.containsKey(key)) hash.put(s, new ArrayList<List>());
            hash.get(key).add(str);        }        return new ArrayList(hash.values());
    }

50. Pow(x, n)

Realize pow( xn ), that is, calculate the n-th power function of x.

Example 1:

输入: 2.00000, 10
输出: 1024.00000

Example 2:

输入: 2.10000, 3
输出: 9.26100

Example 3:

输入: 2.00000, -2
输出: 0.25000
解释: 2-2 = 1/22 = 1/4 = 0.25

Description:

  • -100.0 < x < 100.0
  • n  is a 32-bit signed integer, and its value range is [−231, 231 − 1].
public double myPow(double x, int n) {
        if(x == 0.0f) return 0.0d;
        long b = n;
        double res = 1.0;
        // 当n < 0时,转化为 n >= 0的情况
        if(b < 0){
            x = 1 / x;
            b = -b;
        }
        while(b > 0){
            if((b & 1) == 1) // b % 2 == 1
                res *= x;
            x *= x; // x = x ^ 2
            b >>= 1; // b = b // 2
        }
        return res;
    }

If you think this article is helpful to you, you can like it and follow it to support it, or you can follow my public account. There are more technical dry goods articles and related information sharing on it, everyone learns and progresses together!

Guess you like

Origin blog.csdn.net/weixin_50205273/article/details/108981320