2019-03-08 21:41:45 +08:00
<!-- GFM - TOC -->
* [1. 把数组中的 0 移到末尾 ](#1-把数组中的-0-移到末尾 )
* [2. 改变矩阵维度 ](#2-改变矩阵维度 )
* [3. 找出数组中最长的连续 1 ](#3-找出数组中最长的连续-1 )
* [4. 有序矩阵查找 ](#4-有序矩阵查找 )
* [5. 有序矩阵的 Kth Element ](#5-有序矩阵的-kth-element )
* [6. 一个数组元素在 [1, n] 之间,其中一个数被替换为另一个数,找出重复的数和丢失的数](#6-一个数组元素在-[1,-n]-之间,其中一个数被替换为另一个数,找出重复的数和丢失的数)
* [7. 找出数组中重复的数,数组值在 [1, n] 之间](#7-找出数组中重复的数,数组值在-[1,-n]-之间)
* [8. 数组相邻差值的个数 ](#8-数组相邻差值的个数 )
* [9. 数组的度 ](#9-数组的度 )
* [10. 对角元素相等的矩阵 ](#10-对角元素相等的矩阵 )
* [11. 嵌套数组 ](#11-嵌套数组 )
* [12. 分隔数组 ](#12-分隔数组 )
<!-- GFM - TOC -->
# 1. 把数组中的 0 移到末尾
[283. Move Zeroes (Easy) ](https://leetcode.com/problems/move-zeroes/description/ )
2019-03-08 20:31:07 +08:00
```html
2019-03-08 21:41:45 +08:00
For example, given nums = [0, 1, 0, 3, 12], after calling your function, nums should be [1, 3, 12, 0, 0].
2019-03-08 20:31:07 +08:00
```
```java
2019-03-08 21:41:45 +08:00
public void moveZeroes(int[] nums) {
int idx = 0;
for (int num : nums) {
if (num != 0) {
nums[idx++] = num;
}
}
while (idx < nums.length ) {
nums[idx++] = 0;
}
2019-03-08 20:31:07 +08:00
}
```
2019-03-08 21:41:45 +08:00
# 2. 改变矩阵维度
2019-03-08 20:31:07 +08:00
2019-03-08 21:41:45 +08:00
[566. Reshape the Matrix (Easy) ](https://leetcode.com/problems/reshape-the-matrix/description/ )
2019-03-08 20:31:07 +08:00
```html
Input:
2019-03-08 21:41:45 +08:00
nums =
2019-03-08 20:31:07 +08:00
[[1,2],
2019-03-08 21:41:45 +08:00
[3,4]]
r = 1, c = 4
2019-03-08 20:31:07 +08:00
Output:
[[1,2,3,4]]
Explanation:
2019-03-08 21:41:45 +08:00
The row-traversing of nums is [1,2,3,4]. The new reshaped matrix is a 1 * 4 matrix, fill it row by row by using the previous list.
2019-03-08 20:31:07 +08:00
```
```java
2019-03-08 21:41:45 +08:00
public int[][] matrixReshape(int[][] nums, int r, int c) {
int m = nums.length, n = nums[0].length;
if (m * n != r * c) {
return nums;
}
int[][] reshapedNums = new int[r][c];
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++;
}
}
return reshapedNums;
2019-03-08 20:31:07 +08:00
}
```
2019-03-08 21:41:45 +08:00
# 3. 找出数组中最长的连续 1
2019-03-08 20:31:07 +08:00
2019-03-08 21:41:45 +08:00
[485. Max Consecutive Ones (Easy) ](https://leetcode.com/problems/max-consecutive-ones/description/ )
2019-03-08 20:31:07 +08:00
```java
2019-03-08 21:41:45 +08:00
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;
2019-03-08 20:31:07 +08:00
}
```
2019-03-08 21:41:45 +08:00
# 4. 有序矩阵查找
2019-03-08 20:31:07 +08:00
2019-03-08 21:41:45 +08:00
[240. Search a 2D Matrix II (Medium) ](https://leetcode.com/problems/search-a-2d-matrix-ii/description/ )
2019-03-08 20:31:07 +08:00
```html
[
2019-03-08 21:41:45 +08:00
[ 1, 5, 9],
[10, 11, 13],
[12, 13, 15]
2019-03-08 20:31:07 +08:00
]
```
```java
2019-03-08 21:41:45 +08:00
public boolean searchMatrix(int[][] matrix, int target) {
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) return false;
int m = matrix.length, n = matrix[0].length;
int row = 0, col = n - 1;
while (row < m & & col > = 0) {
if (target == matrix[row][col]) return true;
else if (target < matrix [ row ] [ col ] ) col-- ;
else row++;
}
return false;
2019-03-08 20:31:07 +08:00
}
```
2019-03-08 21:41:45 +08:00
# 5. 有序矩阵的 Kth Element
2019-03-08 20:31:07 +08:00
2019-03-08 21:41:45 +08:00
[378. Kth Smallest Element in a Sorted Matrix ((Medium)) ](https://leetcode.com/problems/kth-smallest-element-in-a-sorted-matrix/description/ )
2019-03-08 20:31:07 +08:00
```html
2019-03-08 21:41:45 +08:00
matrix = [
[ 1, 5, 9],
[10, 11, 13],
[12, 13, 15]
2019-03-08 20:31:07 +08:00
],
2019-03-08 21:41:45 +08:00
k = 8,
2019-03-08 20:31:07 +08:00
2019-03-08 21:41:45 +08:00
return 13.
2019-03-08 20:31:07 +08:00
```
2019-03-08 21:41:45 +08:00
解题参考:[Share my thoughts and Clean Java Code](https://leetcode.com/problems/kth-smallest-element-in-a-sorted-matrix/discuss/85173)
2019-03-08 20:31:07 +08:00
二分查找解法:
```java
2019-03-08 21:41:45 +08:00
public int kthSmallest(int[][] matrix, int k) {
int m = matrix.length, n = matrix[0].length;
int lo = matrix[0][0], hi = matrix[m - 1][n - 1];
while (lo < = hi) {
int mid = lo + (hi - lo) / 2;
int cnt = 0;
for (int i = 0; i < m ; i + + ) {
for (int j = 0; j < n & & matrix [ i ] [ j ] < = mid ; j + + ) {
cnt++;
}
}
if (cnt < k ) lo = mid + 1 ;
else hi = mid - 1;
}
return lo;
2019-03-08 20:31:07 +08:00
}
```
堆解法:
```java
2019-03-08 21:41:45 +08:00
public int kthSmallest(int[][] matrix, int k) {
int m = matrix.length, n = matrix[0].length;
PriorityQueue< Tuple > pq = new PriorityQueue< Tuple > ();
for(int j = 0; j < n ; j + + ) pq . offer ( new Tuple ( 0 , j , matrix [ 0 ] [ j ] ) ) ;
for(int i = 0; i < k - 1 ; i + + ) { / / 小根堆 , 去掉 k - 1 个堆顶元素 , 此时堆顶元素就是第 k 的数
Tuple t = pq.poll();
if(t.x == m - 1) continue;
pq.offer(new Tuple(t.x + 1, t.y, matrix[t.x + 1][t.y]));
}
return pq.poll().val;
2019-03-08 20:31:07 +08:00
}
2019-03-08 21:41:45 +08:00
class Tuple implements Comparable< Tuple > {
int x, y, val;
public Tuple(int x, int y, int val) {
this.x = x; this.y = y; this.val = val;
}
2019-03-08 20:31:07 +08:00
2019-03-08 21:41:45 +08:00
@Override
public int compareTo(Tuple that) {
return this.val - that.val;
}
2019-03-08 20:31:07 +08:00
}
```
2019-03-08 21:41:45 +08:00
# 6. 一个数组元素在 [1, n] 之间,其中一个数被替换为另一个数,找出重复的数和丢失的数
2019-03-08 20:31:07 +08:00
2019-03-08 21:41:45 +08:00
[645. Set Mismatch (Easy) ](https://leetcode.com/problems/set-mismatch/description/ )
2019-03-08 20:31:07 +08:00
```html
2019-03-08 21:41:45 +08:00
Input: nums = [1,2,2,4]
Output: [2,3]
2019-03-08 20:31:07 +08:00
```
```html
2019-03-08 21:41:45 +08:00
Input: nums = [1,2,2,4]
Output: [2,3]
2019-03-08 20:31:07 +08:00
```
2019-03-08 21:41:45 +08:00
最直接的方法是先对数组进行排序,这种方法时间复杂度为 O(NlogN)。本题可以以 O(N) 的时间复杂度、O(1) 空间复杂度来求解。
2019-03-08 20:31:07 +08:00
主要思想是通过交换数组元素,使得数组上的元素在正确的位置上。
```java
2019-03-08 21:41:45 +08:00
public int[] findErrorNums(int[] nums) {
for (int i = 0; i < nums.length ; i + + ) {
while (nums[i] != i + 1 & & nums[nums[i] - 1] != nums[i]) {
swap(nums, i, nums[i] - 1);
}
}
for (int i = 0; i < nums.length ; i + + ) {
if (nums[i] != i + 1) {
return new int[]{nums[i], i + 1};
}
}
return null;
2019-03-08 20:31:07 +08:00
}
2019-03-08 21:41:45 +08:00
private void swap(int[] nums, int i, int j) {
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
2019-03-08 20:31:07 +08:00
}
```
类似题目:
2019-03-08 21:41:45 +08:00
- [448. Find All Numbers Disappeared in an Array (Easy) ](https://leetcode.com/problems/find-all-numbers-disappeared-in-an-array/description/ ),寻找所有丢失的元素
- [442. Find All Duplicates in an Array (Medium) ](https://leetcode.com/problems/find-all-duplicates-in-an-array/description/ ),寻找所有重复的元素。
2019-03-08 20:31:07 +08:00
2019-03-08 21:41:45 +08:00
# 7. 找出数组中重复的数,数组值在 [1, n] 之间
2019-03-08 20:31:07 +08:00
2019-03-08 21:41:45 +08:00
[287. Find the Duplicate Number (Medium) ](https://leetcode.com/problems/find-the-duplicate-number/description/ )
2019-03-08 20:31:07 +08:00
要求不能修改数组,也不能使用额外的空间。
二分查找解法:
```java
2019-03-08 21:41:45 +08:00
public int findDuplicate(int[] nums) {
int l = 1, h = nums.length - 1;
while (l < = h) {
int mid = l + (h - l) / 2;
int cnt = 0;
for (int i = 0; i < nums.length ; i + + ) {
if (nums[i] < = mid) cnt++;
}
if (cnt > mid) h = mid - 1;
else l = mid + 1;
}
return l;
2019-03-08 20:31:07 +08:00
}
```
双指针解法,类似于有环链表中找出环的入口:
```java
2019-03-08 21:41:45 +08:00
public int findDuplicate(int[] nums) {
int slow = nums[0], fast = nums[nums[0]];
while (slow != fast) {
slow = nums[slow];
fast = nums[nums[fast]];
}
fast = 0;
while (slow != fast) {
slow = nums[slow];
fast = nums[fast];
}
return slow;
2019-03-08 20:31:07 +08:00
}
```
2019-03-08 21:41:45 +08:00
# 8. 数组相邻差值的个数
2019-03-08 20:31:07 +08:00
2019-03-08 21:41:45 +08:00
[667. Beautiful Arrangement II (Medium) ](https://leetcode.com/problems/beautiful-arrangement-ii/description/ )
2019-03-08 20:31:07 +08:00
```html
2019-03-08 21:41:45 +08:00
Input: n = 3, k = 2
Output: [1, 3, 2]
Explanation: The [1, 3, 2] has three different positive integers ranging from 1 to 3, and the [2, 1] has exactly 2 distinct integers: 1 and 2.
2019-03-08 20:31:07 +08:00
```
2019-03-08 21:56:42 +08:00
题目描述:数组元素为 1\~n 的整数,要求构建数组,使得相邻元素的差值不相同的个数为 k。
2019-03-08 20:31:07 +08:00
2019-03-08 21:41:45 +08:00
让前 k+1 个元素构建出 k 个不相同的差值, 序列为: 1 k+1 2 k 3 k-1 ... k/2 k/2+1.
2019-03-08 20:31:07 +08:00
```java
2019-03-08 21:41:45 +08:00
public int[] constructArray(int n, int k) {
int[] ret = new int[n];
ret[0] = 1;
for (int i = 1, interval = k; i < = k; i++, interval--) {
ret[i] = i % 2 == 1 ? ret[i - 1] + interval : ret[i - 1] - interval;
}
for (int i = k + 1; i < n ; i + + ) {
ret[i] = i + 1;
}
return ret;
2019-03-08 20:31:07 +08:00
}
```
2019-03-08 21:41:45 +08:00
# 9. 数组的度
2019-03-08 20:31:07 +08:00
2019-03-08 21:41:45 +08:00
[697. Degree of an Array (Easy) ](https://leetcode.com/problems/degree-of-an-array/description/ )
2019-03-08 20:31:07 +08:00
```html
2019-03-08 21:41:45 +08:00
Input: [1,2,2,3,1,4,2]
Output: 6
2019-03-08 20:31:07 +08:00
```
2019-03-08 21:41:45 +08:00
题目描述:数组的度定义为元素出现的最高频率,例如上面的数组度为 3。要求找到一个最小的子数组, 这个子数组的度和原数组一样。
2019-03-08 20:31:07 +08:00
```java
2019-03-08 21:41:45 +08:00
public int findShortestSubArray(int[] nums) {
Map< Integer , Integer > numsCnt = new HashMap< >();
Map< Integer , Integer > numsLastIndex = new HashMap< >();
Map< Integer , Integer > numsFirstIndex = new HashMap< >();
for (int i = 0; i < nums.length ; i + + ) {
int num = nums[i];
numsCnt.put(num, numsCnt.getOrDefault(num, 0) + 1);
numsLastIndex.put(num, i);
if (!numsFirstIndex.containsKey(num)) {
numsFirstIndex.put(num, i);
}
}
int maxCnt = 0;
for (int num : nums) {
maxCnt = Math.max(maxCnt, numsCnt.get(num));
}
int ret = nums.length;
for (int i = 0; i < nums.length ; i + + ) {
int num = nums[i];
int cnt = numsCnt.get(num);
if (cnt != maxCnt) continue;
ret = Math.min(ret, numsLastIndex.get(num) - numsFirstIndex.get(num) + 1);
}
return ret;
2019-03-08 20:31:07 +08:00
}
```
2019-03-08 21:41:45 +08:00
# 10. 对角元素相等的矩阵
2019-03-08 20:31:07 +08:00
2019-03-08 21:41:45 +08:00
[766. Toeplitz Matrix (Easy) ](https://leetcode.com/problems/toeplitz-matrix/description/ )
2019-03-08 20:31:07 +08:00
```html
1234
5123
9512
2019-03-08 21:41:45 +08:00
In the above grid, the diagonals are "[9]", "[5, 5]", "[1, 1, 1]", "[2, 2, 2]", "[3, 3]", "[4]", and in each diagonal all elements are the same, so the answer is True.
2019-03-08 20:31:07 +08:00
```
```java
2019-03-08 21:41:45 +08:00
public boolean isToeplitzMatrix(int[][] matrix) {
for (int i = 0; i < matrix [ 0 ] . length ; i + + ) {
if (!check(matrix, matrix[0][i], 0, i)) {
return false;
}
}
for (int i = 0; i < matrix.length ; i + + ) {
if (!check(matrix, matrix[i][0], i, 0)) {
return false;
}
}
return true;
2019-03-08 20:31:07 +08:00
}
2019-03-08 21:41:45 +08:00
private boolean check(int[][] matrix, int expectValue, int row, int col) {
if (row >= matrix.length || col >= matrix[0].length) {
return true;
}
if (matrix[row][col] != expectValue) {
return false;
}
return check(matrix, expectValue, row + 1, col + 1);
2019-03-08 20:31:07 +08:00
}
```
2019-03-08 21:41:45 +08:00
# 11. 嵌套数组
2019-03-08 20:31:07 +08:00
2019-03-08 21:41:45 +08:00
[565. Array Nesting (Medium) ](https://leetcode.com/problems/array-nesting/description/ )
2019-03-08 20:31:07 +08:00
```html
2019-03-08 21:41:45 +08:00
Input: A = [5,4,0,3,1,6,2]
Output: 4
2019-03-08 20:31:07 +08:00
Explanation:
2019-03-08 21:41:45 +08:00
A[0] = 5, A[1] = 4, A[2] = 0, A[3] = 3, A[4] = 1, A[5] = 6, A[6] = 2.
2019-03-08 20:31:07 +08:00
2019-03-08 21:41:45 +08:00
One of the longest S[K]:
S[0] = {A[0], A[5], A[6], A[2]} = {5, 6, 2, 0}
2019-03-08 20:31:07 +08:00
```
2019-03-08 21:41:45 +08:00
题目描述: S[i] 表示一个集合,集合的第一个元素是 A[i],第二个元素是 A[A[i]],如此嵌套下去。求最大的 S[i]。
2019-03-08 20:31:07 +08:00
```java
2019-03-08 21:41:45 +08:00
public int arrayNesting(int[] nums) {
int max = 0;
for (int i = 0; i < nums.length ; i + + ) {
int cnt = 0;
for (int j = i; nums[j] != -1; ) {
cnt++;
int t = nums[j];
nums[j] = -1; // 标记该位置已经被访问
j = t;
}
max = Math.max(max, cnt);
}
return max;
2019-03-08 20:31:07 +08:00
}
```
2019-03-08 21:41:45 +08:00
# 12. 分隔数组
2019-03-08 20:31:07 +08:00
2019-03-08 21:41:45 +08:00
[769. Max Chunks To Make Sorted (Medium) ](https://leetcode.com/problems/max-chunks-to-make-sorted/description/ )
2019-03-08 20:31:07 +08:00
```html
2019-03-08 21:41:45 +08:00
Input: arr = [1,0,2,3,4]
Output: 4
2019-03-08 20:31:07 +08:00
Explanation:
2019-03-08 21:41:45 +08:00
We can split into two chunks, such as [1, 0], [2, 3, 4].
However, splitting into [1, 0], [2], [3], [4] is the highest number of chunks possible.
2019-03-08 20:31:07 +08:00
```
题目描述:分隔数组,使得对每部分排序后数组就为有序。
```java
2019-03-08 21:41:45 +08:00
public int maxChunksToSorted(int[] arr) {
if (arr == null) return 0;
int ret = 0;
int right = arr[0];
for (int i = 0; i < arr.length ; i + + ) {
right = Math.max(right, arr[i]);
if (right == i) ret++;
}
return ret;
2019-03-08 20:31:07 +08:00
}
```
2019-03-11 09:50:13 +08:00
2019-03-15 21:40:56 +08:00
< / br > < div align = "center" > 公众号 CyC2018, 专注于核心基础知识、求职指导、技术成长。在公众号后台回复 ziliao 可领取复习大纲,帮你理清复习重点。< / div > < / br >
2019-03-11 09:18:22 +08:00
< div align = "center" > < img width = "180px" src = "https://cyc-1256109796.cos.ap-guangzhou.myqcloud.com/%E5%85%AC%E4%BC%97%E5%8F%B7.jpg" > < / img > < / div >