数组与矩阵问题总结

本篇文章目的是总结数组问题共有哪几大类,每类的解题核心思路和解法。具体的思路转code的能力见其他一篇讲一种算法的独立篇目。

1. 排序问题

(1)快速排序
(2)桶排序
(3)荷兰国旗问题
(4)希尔排序
希尔排序原理:分组+插入排序
每次分组:希尔增量k = k/2
插入排序:对每次分出的数个组,组内都进行插入排序。

插入排序原理:
和前面的数比较and交换。每次都把new input和前面的数换到不能换了为止。

时间空间复杂度:
插入排序的时间复杂度:O(n)~ O(n2),平均O(n2)
希尔排序的时间复杂度:O(nlogn)~ O(n2or1.5), 平均O(n1.5or1.25)。具体复杂度取决于使用何种增量:希尔增量orHibbard增量。
在这里插入图片描述

2. Given有序数组的问题

3. 找某种数

(1)最多重复的数
(2)第K大的数

4. 循环数组

5. Leetcode 题解 - 数组与矩阵

  1. 把数组中的 0 移到末尾
    <1> 题目要求:
    maintaining the relative order of the non-zero elements
    in-place: without making a copy of the array
    Minimize the total number of operations

<2> 解题思路:双指针+swap。目的是把所有不等于0的数组元素按原先顺序“交换到数组前部。
快指针遍历所有数组元素,如果元素不等于0,则和慢指针指向的元素交换(换完慢指针指向非零元素),然后慢指针向前挪动一步。

<3> code:

class Solution {
    public void swap(int[] nums, int i, int idx){
        int temp = nums[idx];
        nums[idx] = nums[i];
        nums[i] = temp;
    }
    
    public void moveZeroes(int[] nums) {
        int j = 0;
        for (int i = 0; i < nums.length; i++){
            if (nums[i] != 0){
                swap(nums, i, j);
                j++;
            }
        }
    }
}

  1. 改变矩阵维度
    <1> 题目要求
    the same row-traversing order as they were.
    If the ‘reshape’ operation with given parameters is possible and legal, output the new reshaped matrix; Otherwise, output the original matrix.

<2> 考察基础知识:多维数组比如2d array

定义:
int[ ][ ] arr = new int[10][20];
初始化:
int[ ][ ] arr = {{1, 2}, {3, 4}};
打印:
for (int i = 0; i < B.length; i++) {
    for (int j = 0; j < B[0].length; j++) {
         System.out.print(B[i][j] + " ");
    }
    System.out.println();
}

<3> 解题思路:
设原数组为A_mxn,被reshape后的数组为B_rxc。
若A的元素个数不等于B,则返回A;
若等于,则开始reshape操作。
核心思想:同时遍历两个大小不一样的矩阵(2d array)A和B,将A中的值赋给B。
如何实现:我们不能同时循环读取两个数组的元素,把A的元素赋给B,所以我们通过A[index/nums_column][index%nums_column]的形式读取A中的元素,用ij循环赋值给B。每赋值一次,index++。
index/#Acolumns = #Arows
index%#Acolumns = #Acolumns

<4> code:

public int[][] matrixReshape(int[][] nums, int r, int c) {
    int m = nums.length, n = nums[0].length; //the number of rows and columns of A 
    //cannot reshape
    if (m * n != r * c) {
        return nums; 
    }
    //can reshape, define the reshaped matrix B
    int[][] reshapedNums = new int[r][c];
    //核心操作:同时遍历两个大小不一样的矩阵(2d array)A和B,将A中的值赋给B
    int index = 0;
    for (int i = 0; i < r; i++) {
        for (int j = 0; j < c; j++) {
            reshapedNums[i][j] = nums[index / n][index % n];//index/#Acolumns = #Arows, index%#Acolumns = #Acolumns
            index++;
        }
    }
    return reshapedNums;
}
//打印数组B看效果
public static void main(String[] args) {
        int[][] A = {{2, 5}, {4, 6}, {1, 7},{3, 9}};
        int m = A.length; int n = A[0].length;
        int[][] B = matrixReshape(A, 2, 4);
        for (int i = 0; i < B.length; i++) {
            for (int j = 0; j < B[0].length; j++) {
                System.out.print(B[i][j] + " ");
            }
            System.out.println();
        }
    }
  1. 找出数组中最长的连续 1
    <1> 题目要求: 数组中只有0或1两种值。
    <2> 解题思路: 两个变量,max count和current count。当遍历数组时,判断,如果数组元素为1,更新current count,如果不为1,将count归0。当current count > max count时,更新max count。
    <3> 小技巧:三目运算符(简写版的if-else)
    String mood = (isHappy == true)?“I’m Happy!”:“I’m Sad!”;
    if isHappy, then “I’m Happy!”. “I’m Sad!” otherwise.
    <4> code:
public int findMaxConsecutiveOnes(int[] nums) {
    int max = 0, cur = 0;
    for (int x : nums) {
        cur = x == 0 ? 0 : cur + 1;
        max = Math.max(max, cur);
    }
    return max;
}
  1. 有序矩阵查找
    <1> 题目要求:
    m == matrix.length
    n == matrix[i].length
    All the integers in each row are sorted in ascending order.
    All the integers in each column are sorted in ascending order.
    <2> 基础知识:2d array? matrix?
    You have a multi dimensional array. Thus, there is more than one dimension. Each dimension has a length. With block.length you get the length of the first one (i.e. 50), with block[x].length, you get the length of the second one (i.e., 70).

When the multi-dimensional array is used to represent a matrix, all block[x].length will be equal, no matter what you choose for x. However, you could have an array where the nested arrays have different lengths, then block[0].length might not be equal to block[1].length.
<3> 解题思路:
corner case: 矩阵的行or列 = 0 (空矩阵null的行and列都=0)
右上角是个很特殊的位置。如果target大于当前右上角的值,则去掉当前行(向下走一格,row++)。如果target小于当前右上角的值,则去掉当前列(向左走一格,col–)。
也可以和二叉搜索树类比:向左走进入左子树,一定小于当前节点的值;向右走进入右子树,一定大于当前节点的值。
<4> code:

public boolean searchMatrix(int[][] matrix, int target) {
    if (matrix.length == 0 || matrix[0].length == 0) {
        return false;
    }
    int row = 0;
    int col = matrix[0].length - 1;
    while (row < matrix.length && col >= 0) {
        if (target > matrix[row][col]) {
            row++;
        } else if (target < matrix[row][col]) {
            col--;
        } else {
            return true;
        }
    }
    return false;
}
  1. 有序矩阵的 Kth Element

  2. 一个数组元素在 [1, n] 之间,其中一个数被替换为另一个数,找出重复的数和丢失的数

  3. 找出数组中重复的数,数组值在 [1, n] 之间

  4. 数组相邻差值的个数

  5. 数组的度

  6. 对角元素相等的矩阵

  7. 嵌套数组

  8. 分隔数组

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值