LeetCode刷题

作者: SHAN某人 | 来源:发表于2021-09-15 16:57 被阅读0次

713. 乘积小于K的子数组

链接:https://leetcode-cn.com/problems/subarray-product-less-than-k

给定一个正整数数组 nums和整数 k 。
请找出该数组内乘积小于 k 的连续的子数组的个数。
示例 1:
输入: nums = [10,5,2,6], k = 100
输出: 8
解释: 8个乘积小于100的子数组分别为: [10], [5], [2], [6], [10,5], [5,2], [2,6], [5,2,6]。
需要注意的是 [10,5,2] 并不是乘积小于100的子数组。
提示: 

1 <= nums.length <= 3 * 104
1 <= nums[i] <= 1000
0 <= k <= 106

滑动窗口问题
正向滑动窗口可能导致大量重复计算
如 1,2,3,4
[1],[1,2],[1,2,3],[2]

 public int numSubarrayProductLessThanK2(int[] nums, int k) {
        int start = 0;
        int count = 0;
        while (start < nums.length) {
            int end = start;
            int product = nums[start];
            while ( end < nums.length && product  < k){
                count++;
                end++;
                if(end<nums.length){
                    product = product * nums[end];
                }
            }
            start++;
        }
        return count;
    }

如果需要优化,节省计算,则需要发现规律。
规律,找到一个区间 [left,right],这个区间所有连续子数组都满足条件,且连续子数组的个数为 right- left + 1

  public int numSubarrayProductLessThanK(int[] nums, int k) {
        if (k <= 1) return 0;
        int prod = 1, ans = 0, left = 0;
        for (int right = 0; right < nums.length; right++) {
            prod *= nums[right];
            while (prod >= k) prod /= nums[left++];
            ans += right - left + 1;
        }
        return ans;
    }
# 每次到这个位置, 我们会得到一些以right结尾的乘积小于k的连续子数组, 这些子数组不会与之前的任何一个重复:
# [right]
# [right-1, right]
# [right-2, right]
# [right-3, right-2, right]
# ...
# [left, ..., right-3, right-2, right]
# 很明显一共有right - left + 1个
res += right - left + 1

200. 岛屿数量

给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。

岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。

此外,你可以假设该网格的四条边均被水包围。

输入:grid = [
  ["1","1","0","0","0"],
  ["1","1","0","0","0"],
  ["0","0","1","0","0"],
  ["0","0","0","1","1"]
]
输出:3

核心思路就是找一个点作为起始点,然后进行广搜,将遍历过的陆地都变成海洋。
找起始点的过程为遍历整个二维数组,如果遇到陆地(元素值为 ‘1’)就记岛屿数加1;
BFS 广搜解决
有个技巧是广搜扩展新节点的过程中就将陆地变成海洋,而不是队列吐出的时候,这样可以减少后续的计算量。

  public int numIslands(char[][] grid) {
        int num_islands = 0;
        for (int row = 0; row < grid.length; row++) {
            for (int col = 0; col < grid[row].length; col++) {
                // 若当前元素值为1
                if(grid[row][col]== '1'){
                    ++num_islands;
                    grid[row][col] = '0'; // 标记为0 表示已经访问
                    LinkedList<Pair<Integer, Integer>> neighbors = new LinkedList<>();  // 启用队列进行广度搜索
                    neighbors.add(new Pair<>(row,col));

                    while (!neighbors.isEmpty()){
                        Pair<Integer,Integer> pair = neighbors.pop();
                        int currentRow = pair.getKey(),currentCol = pair.getValue();
                        // 访问队首节点的上下左右节点,如果有为1的情况则将其入队
                        if(currentRow-1 >=0 && grid[currentRow-1][currentCol] == '1') {  // 上
                            neighbors.add(new Pair<>(currentRow-1,currentCol));
                            grid[currentRow-1][currentCol] = '0';  // 标记访问
                        }
                        if(currentRow+1 < grid.length && grid[currentRow+1][currentCol] == '1') {  // 下
                            neighbors.add(new Pair<>(currentRow+1,currentCol));
                            grid[currentRow+1][currentCol] = '0';  // 标记访问
                        }
                        if(currentCol-1 >=0 && grid[currentRow][currentCol-1] == '1') {  // 左
                            neighbors.add(new Pair<>(currentRow,currentCol-1));
                            grid[currentRow][currentCol-1] = '0';  // 标记访问
                        }
                        if(currentCol+1 < grid[currentRow].length && grid[currentRow][currentCol+1] == '1') {  // 右
                            neighbors.add(new Pair<>(currentRow,currentCol+1));
                            grid[currentRow][currentCol+1] = '0';  // 标记访问
                        }
                    }

                }
            }
        }
        return num_islands;
    }

547. 省份数量

有 n 个城市,其中一些彼此相连,另一些没有相连。如果城市 a 与城市 b 直接相连,且城市 b 与城市 c 直接相连,那么城市 a 与城市 c 间接相连。

省份 是一组直接或间接相连的城市,组内不含其他没有相连的城市。

给你一个 n x n 的矩阵 isConnected ,其中 isConnected[i][j] = 1 表示第 i 个城市和第 j 个城市直接相连,而 isConnected[i][j] = 0 表示二者不直接相连。

返回矩阵中 省份 的数量。


例子

和岛屿数量一样的题,只是换成了邻接矩阵表示法,深搜 广搜都可,还有种解法是并查集。
不过手写并查集比较费劲,不建议面试的时候尝试。

 /**
     *
     * @param isConnected  图的邻接矩阵表示法
     * @return  广度优先遍历
     */
    public int findCircleNum2(int[][] isConnected) {
        int[] visited = new int[isConnected.length];
        int provinceCnt = 0;
        for (int nodeIndex = 0; nodeIndex < isConnected.length; nodeIndex++) {
                LinkedList<Integer>  queue = new LinkedList<>();
                if(visited[nodeIndex] == 1) continue;
                visited[nodeIndex] = 1;
                queue.add(nodeIndex);
                provinceCnt++;
                while (!queue.isEmpty()){
                     Integer visitNode =  queue.poll();
                    for (int i = 0; i < isConnected[visitNode].length; i++) {
                        if( isConnected[visitNode][i] ==1 && i != visitNode && visited[i]!=1){
                            visited[i] = 1;
                            queue.add(i);
                        }
                    }
                }
        }
        return provinceCnt;
    }

    /**
     * 深度优先遍历
     */
    public int findCircleNum(int[][] isConnected) {
        int[] visited = new int[isConnected.length];
        int provinceCnt = 0;
        for (int nodeIndex = 0; nodeIndex < isConnected.length; nodeIndex++) {
            Stack<Integer>  stack = new Stack<>();
            if(visited[nodeIndex] == 1) continue;
            visited[nodeIndex] = 1;
            stack.add(nodeIndex);
            provinceCnt++;
            while (!stack.isEmpty()){
                Integer visitNode =  stack.pop();
                for (int i = 0; i < isConnected[visitNode].length; i++) {
                    if( isConnected[visitNode][i] ==1 && i != visitNode && visited[i]!=1){
                        visited[i] = 1;
                        stack.add(i);
                    }
                }
            }
        }
        return provinceCnt;
    }

相关文章

网友评论

    本文标题:LeetCode刷题

    本文链接:https://www.haomeiwen.com/subject/hwxlgltx.html