Leetcode題解——數據結構之數組與矩陣


1. 把數組中的 0 移到末尾

1. 把數組中的 0 移到末尾

283. Move Zeroes (Easy)

For example, given nums = [0, 1, 0, 3, 12], after calling your function, nums should be [1, 3, 12, 0, 0].
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; } }

2. 改變矩陣維度

566. Reshape the Matrix (Easy)

Input:
nums =
[[1,2],
 [3,4]]
r = 1, c = 4

Output:
[[1,2,3,4]]

Explanation:
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.
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; }

3. 找出數組中最長的連續 1

485. Max Consecutive Ones (Easy)

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; }

4. 有序矩陣查找

240. Search a 2D Matrix II (Medium)

[
   [ 1,  5,  9],
   [10, 11, 13],
   [12, 13, 15]
]
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; }

5. 有序矩陣的 Kth Element

378. Kth Smallest Element in a Sorted Matrix ((Medium))

matrix = [
  [ 1,  5,  9],
  [10, 11, 13],
  [12, 13, 15]
],
k = 8,

return 13.

解題參考:Share my thoughts and Clean Java Code

二分查找解法:

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; }

堆解法:

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; } 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; } @Override public int compareTo(Tuple that) { return this.val - that.val; } }

6. 一個數組元素在 [1, n] 之間,其中一個數被替換為另一個數,找出重復的數和丟失的數

645. Set Mismatch (Easy)

Input: nums = [1,2,2,4]
Output: [2,3]
Input: nums = [1,2,2,4]
Output: [2,3]

最直接的方法是先對數組進行排序,這種方法時間復雜度為 O(NlogN)。本題可以以 O(N) 的時間復雜度、O(1) 空間復雜度來求解。

主要思想是通過交換數組元素,使得數組上的元素在正確的位置上。

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; } private void swap(int[] nums, int i, int j) { int tmp = nums[i]; nums[i] = nums[j]; nums[j] = tmp; }

類似題目:

7. 找出數組中重復的數,數組值在 [1, n] 之間

287. Find the Duplicate Number (Medium)

要求不能修改數組,也不能使用額外的空間。

二分查找解法:

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; }

雙指針解法,類似於有環鏈表中找出環的入口:

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; }

8. 數組相鄰差值的個數

667. Beautiful Arrangement II (Medium)

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.

題目描述:數組元素為 1~n 的整數,要求構建數組,使得相鄰元素的差值不相同的個數為 k。

讓前 k+1 個元素構建出 k 個不相同的差值,序列為:1 k+1 2 k 3 k-1 ... k/2 k/2+1.

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; }

9. 數組的度

697. Degree of an Array (Easy)

Input: [1,2,2,3,1,4,2]
Output: 6

題目描述:數組的度定義為元素出現的最高頻率,例如上面的數組度為 3。要求找到一個最小的子數組,這個子數組的度和原數組一樣。

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; }

10. 對角元素相等的矩陣

766. Toeplitz Matrix (Easy)

1234
5123
9512

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.
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; } 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); }

11. 嵌套數組

565. Array Nesting (Medium)

Input: A = [5,4,0,3,1,6,2]
Output: 4
Explanation:
A[0] = 5, A[1] = 4, A[2] = 0, A[3] = 3, A[4] = 1, A[5] = 6, A[6] = 2.

One of the longest S[K]:
S[0] = {A[0], A[5], A[6], A[2]} = {5, 6, 2, 0}

題目描述:S[i] 表示一個集合,集合的第一個元素是 A[i],第二個元素是 A[A[i]],如此嵌套下去。求最大的 S[i]。

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; }

12. 分隔數組

769. Max Chunks To Make Sorted (Medium)

Input: arr = [1,0,2,3,4]
Output: 4
Explanation:
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.

題目描述:分隔數組,使得對每部分排序后數組就為有序。

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; }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM