刷题笔记--数组

49 阅读1分钟

数组

前缀和:寻找数组中心索引

image-20220218120523078


class Solution {
    public int findMiddleIndex(int[] nums) {
        int total = Arrays.stream(nums).sum();
        int sum = 0;
        for (int i = 0; i < nums.length; i++) {
            //思路:左侧元素之和sum与右侧元素之和相等的话,sum * 2 + nums[i] == total
            if (sum * 2 + nums[i] == total){
                return i;
            }
            sum += nums[i];
        }
        return -1;
    }
}

二分法:搜索插入位置

image-20220218123748161

class Solution1 {
    public int searchInsert(int[] nums, int target) {
        // 二分法
        int left = 0;
        int right = nums.length -1;
        while (left <= right){
            //为什么不用(left+right)/2  防止 left+right 整型溢出
            int mid = left + (right - left) / 2;
            if(nums[mid] == target){
                return mid;
            }else if(nums[mid] < target){
                left = mid + 1;
            }else{
                right = mid + 1;
            }
        }
        return left;
    }
}

合并区间

image-20220218124101886

class Solution3 {
    public int[][] merge(int[][] intervals) {
        //1、对二维数组按照第一列升序排序
        Arrays.sort(intervals, (a,b) -> a[0] -b[0]);
        //2、进行合并数组
        List<int[]> list = new ArrayList<>();//不知道最终数组大小,先用动态数组存放
        int[] term = intervals[0];//临时空间,1 判断是否需要合并集合,2 是否放入结果集

        for (int i = 1; i < intervals.length; i++) {

            if(term[1] < intervals[i][0]){
                //如果前面term的右区间小于等于当前term的左区间,则说明没有重复,直接添加term进入list
                list.add(term);
                //更新term为当前term
                term = intervals[i];
            }else{
                //有重复则更新term右区间
                term[1] = Math.max(term[1],intervals[i][1]);
            }
        }
        //最后的term只更新了右区间,没有添加进list。别忘记添加进list。
        list.add(term);
        return list.toArray(new int[list.size()][2]);
    }
}

二维数组

旋转矩阵

image-20220218160823187

方法一:使用辅助数组

解题思路:martix [row] [col] = marxit [col] [mratix.len - 1 - row]

    public void rotate(int[][] matrix) {
        int len = matrix.length;
        int[][] result = new int[len][len];
        //martix [row] [col] = marxit [col] [mratix.length - 1 - row]
        for (int i = 0; i < len; i++) {
            for (int j = 0; j < len; j++) {
                result[j][len - 1 - i] = matrix [i][j];
            }
        }
        //将结果矩阵result复制回原矩阵
        for (int i = 0; i < len; i++) {
            for (int j = 0; j < len; j++) {
                matrix[i][j] = result[i][j];
            }
        }
    }

时间复杂度:O(N^2^),其中 N 是 matrix 的边长。

空间复杂度:O(N^2^)。我们需要使用一个和 matrix大小相同的辅助数组。

方法二:先水平反转 然后按对角线翻转

解题思路

image-20220218162836560

  1. 水平翻转 : 只需枚举上半部矩阵
  2. 主对角线翻转 :只需枚举主对角线左侧矩阵
 public void rotate(int[][] matrix) {
        int n = matrix.length;
        //水平翻转 matrix[i][j] <=> matrix[n - 1 - i][j]
        for (int i = 0; i < n / 2; i++) {
            for (int j = 0; j < n; j++) {
                int temp = matrix[i][j];
                matrix[i][j] = matrix[n - 1 - i][j];
                matrix[n - 1 - i][j] = temp;
            }
        }
        //对角线翻转 matrix[i][j] <=> matrix[j][i]
        for (int i = 0; i < n ; i++) {
            for (int j = 0; j < i ; j++) {
                int temp = matrix[i][j];
                matrix[i][j] = matrix[j][i];
                matrix[j][i] = temp;
            }
        }
    }