本篇文章目的是总结数组问题共有哪几大类,每类的解题核心思路和解法。具体的思路转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 题解 - 数组与矩阵
- 把数组中的 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> 题目要求
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> 题目要求: 数组中只有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> 题目要求:
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;
}
-
有序矩阵的 Kth Element
-
一个数组元素在 [1, n] 之间,其中一个数被替换为另一个数,找出重复的数和丢失的数
-
找出数组中重复的数,数组值在 [1, n] 之间
-
数组相邻差值的个数
-
数组的度
-
对角元素相等的矩阵
-
嵌套数组
-
分隔数组