Leetcode 题解 - 数组与矩阵

140 阅读1分钟

1. 移动零

Leetcode (opens new window)/ 力扣

class Solution {
    // 双指针
    // j 从左至右找不为 0 的数
    // i 负责维护数组的边界
    public void moveZeroes(int[] nums) {
        int i = 0;
        int j = 0;
        int n = nums.length;

        while (j < n) {
            if (nums[j] != 0) {
                int temp = nums[i];
                nums[i] = nums[j];
                nums[j] = temp;
                i++;
            }
            j++;
        }
    }
}
class Solution {
    public void moveZeroes(int[] nums) {
        int j = 0;

        for (int i = 0; i < nums.length; i++) {
            if (nums[i] != 0) {
                nums[j++] = nums[i];
            }
        }

        for (int i = j; i < nums.length; i++) {
            nums[i] = 0;
        }
    }
}


2. 重塑矩阵

Leetcode (opens new window)/ 力扣

class Solution {
    public int[][] matrixReshape(int[][] mat, int r, int c) {
        int matR = mat.length;
        int matC = mat[0].length;

        if (matC * matR != r * c) {
            return mat;
        }

        int[][] result = new int[r][c];
        int index = 0;
        for (int i = 0; i < r; i++) {
            for (int j = 0; j < c; j++) {
                result[i][j] = mat[index / matC][index % matC];
                index++;
            }
        }
        return result;
    }
}


3. 最大连续 1 的个数

Leetcode (opens new window)/ 力扣

class Solution {
    public int findMaxConsecutiveOnes(int[] nums) {
        int max = 0;
        Map<Integer, Integer> map = new HashMap<>();

        for (int i = 0; i < nums.length; i++) {
            if (nums[i] == 1) {
                int value = map.getOrDefault(i - 1, 0) + 1;
                if (value > max) {
                    max = value;
                }
                map.put(i, value);
            }
        }

        return max;
    }
}

进行优化

class Solution {
    public int findMaxConsecutiveOnes(int[] nums) {
        int last = 0;
        int max = 0;

        for (int i = 0; i < nums.length; i++) {
            if (nums[i] == 1) {
                last = last + 1;
                if (last > max) {
                    max = last;
                }
            } else {
                last = 0;
            }
        }

        return max;
    }
}


4. 搜索二维矩阵 II

Leetcode (opens new window)/ 力扣

class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        int i = matrix.length - 1;
        int j = 0;

        // 从左下角开始找
        while (i >= 0 && j < matrix[i].length) {
            if (matrix[i][j] == target) {
                return true;
            }

            // 如果大于就向上一行去找
            if (matrix[i][j] > target) {
                i--;
            // 如果小于就向左一列去找    
            } else if (matrix[i][j] < target) {
                j++;
            }
        }

        return false;
    }
}


5. 有序矩阵的 Kth Element *

Leetcode (opens new window)/ 力扣



6. 错误的集合

Leetcode (opens new window)/ 力扣

class Solution {
    public int[] findErrorNums(int[] nums) {
        Map<Integer, Integer> map = new HashMap<>();
        int n = nums.length;

        for (int num : nums) {
            map.put(num, map.getOrDefault(num, 0) + 1);
        }

        int[] result = new int[2];

        for (int i = 0; i <= n; i++) {
            int count = map.getOrDefault(i, 0);

            if (count == 2) {
                result[0] = i;
            }
            if (count == 0) {
                result[1] = i;
            }
        }

        return result;
    }
}


7. 寻找重复数

Leetcode (opens new window)/ 力扣(opens new window)

要求不能修改数组,也不能使用额外的空间。

参考题解

双指针法:

class Solution {
    public int findDuplicate(int[] nums) {
        int slow = 0;
        int fast = 0;

        slow = nums[slow];
        fast = nums[nums[fast]];

        // 进入环
        while (slow != fast) {
            slow = nums[slow];
            fast = nums[nums[fast]];
        }

        int pre1 = 0;
        int pre2 = slow;

        // 找环的入口
        while (pre1 != pre2) {
            pre1 = nums[pre1];
            pre2 = nums[pre2];
        }

        return pre1;
    }
}


8. 优美的排列 II

Leetcode (opens new window)/ 力扣

class Solution {
    public int[] constructArray(int n, int k) {
        int[] result = new int[n];

        // 构造一部分等差数列
        for (int i = 0; i < n - k - 1; i++) {
            result[i] = i + 1;
        }

        int left = n - k;
        int right = n;
        int j = 0;

        // 构造一部分交错数列
        for (int i = n - k - 1; i < n; i++) {
            if (j % 2 == 0) {
                result[i] = left;
                left++;
            } else {
                result[i] = right;
                right--;
            }
            j++;
        }

        return result;
    }
}


9. 数组的度

Leetcode (opens new window)/ 力扣

class Solution {
    public int findShortestSubArray(int[] nums) {
        // 元素为 key,值为一个 int 类型的数组
        // 数组:[0] 为 出现的次数,[1] 为第一次出现的位置
        // [2] 为最后一次出现的位置
        Map<Integer, int[]> map = new HashMap<>();

        // 存入哈希表
        for (int i = 0; i < nums.length; i++) {
            if (map.containsKey(nums[i])) {
                map.get(nums[i])[0]++;
                map.get(nums[i])[2] = i;
            } else {
                int[] value = new int[3];
                value[0] = 1;
                value[1] = i;
                value[2] = i;
                map.put(nums[i], value);
            }
        }

        int maxNum = 0;
        int minSize = 0;

        for (Map.Entry<Integer, int[]> entry : map.entrySet()) {
            int[] value = entry.getValue();
            // 如果小于说明这才是数组的度
            if (maxNum < value[0]) {
                maxNum = value[0];
                minSize = value[2] - value[1] + 1;
            // 当度相同时,判断谁的连续子数组的的最短,将其返回
            } else if (maxNum == value[0]) {
                minSize = Math.min(minSize, value[2] - value[1] + 1);
            }
        }

        return minSize;
    }
}


10. 对角元素相等的矩阵

Leetcode (opens new window)/ 力扣

class Solution {
    public boolean isToeplitzMatrix(int[][] matrix) {
        if (matrix == null) {
            return false;
        }

        for (int i = 0; i < matrix.length - 1; i++) {
            for (int j = 0; j < matrix[i].length -1; j++) {
                if (matrix[i][j] != matrix[i + 1][j + 1]) {
                    return false;
                }
            }
        }

        return true;
    }
}


11. 数组嵌套 *

Leetcode (opens new window)/ 力扣

参考题解

class Solution {
    public int arrayNesting(int[] nums) {
        int result = 0;

        for (int i = 0; i < nums.length; i++) {
            if (nums[i] != Integer.MAX_VALUE) {
                int start = nums[i];
                int count = 0;

                while (nums[start] != Integer.MAX_VALUE) {
                    int temp = start;
                    start = nums[start];
                    count++;
                    nums[temp] = Integer.MAX_VALUE;
                }
                result = Math.max(result, count);
            }
        }

        return result;
    }
}


12. 最多能完成排序的块

Leetcode (opens new window)/ 力扣

class Solution {
    public int maxChunksToSorted(int[] arr) {
        int max = 0;
        int result = 0;

        for (int i = 0; i < arr.length; i++) {
            max = Math.max(max, arr[i]);

            // 如果某一段的最大值等于当前下标
            // 说明这一段k
            if (max == i) {
                result++;
            }
        }

        return result;
    }
}