Given a 2D integer array nums
, return all elements of nums
in diagonal order as shown in the below images.
Example 1:
Input: nums = [[1,2,3],[4,5,6],[7,8,9]] Output: [1,4,2,7,5,3,8,6,9]
Example 2:
Input: nums = [[1,2,3,4,5],[6,7],[8],[9,10,11],[12,13,14,15,16]] Output: [1,6,2,8,7,3,9,4,12,10,5,13,11,14,15,16]
Constraints:
1 <= nums.length <= 105
1 <= nums[i].length <= 105
1 <= sum(nums[i].length) <= 105
1 <= nums[i][j] <= 105
This problem asks us to traverse a 2D array diagonally and return the elements in the order they appear on the diagonals. The diagonals are traversed from top-left to bottom-right, with elements on the same diagonal appearing consecutively in the output.
Approach:
The key observation is that all elements on the same diagonal share the same sum of their row and column indices (i+j). Diagonals further down (towards the bottom-right) have larger i+j values. Within the same diagonal, elements are ordered by increasing column index (j). This allows us to sort the elements based on these properties.
The algorithm proceeds as follows:
Create a list of tuples: Iterate through the input nums
array. For each element nums[i][j]
, create a tuple (i+j, j, nums[i][j])
. This tuple represents the element's diagonal (i+j), its column index (j), and its value.
Sort the tuples: Sort the list of tuples based on the first two elements of each tuple:
i+j
(diagonal index). Elements on the same diagonal will be grouped together.j
(column index). Within a diagonal, elements are ordered by increasing column index.Extract and return values: Finally, extract the third element (the value nums[i][j]
) from each sorted tuple and return them as a list.
Time Complexity: O(MN log(MN)), where M is the number of rows and N is the maximum number of columns in nums
. This is dominated by the sorting step, which involves sorting M*N tuples.
Space Complexity: O(M*N), to store the tuples.
Code Implementation (Python):
class Solution:
def findDiagonalOrder(self, nums: List[List[int]]) -> List[int]:
arr = []
for i, row in enumerate(nums):
for j, v in enumerate(row):
arr.append((i + j, j, v)) # Tuple: (diagonal index, column index, value)
arr.sort() # Sorts based on diagonal index then column index
return [v[2] for v in arr] # Extracts and returns the values
Code Implementation (Java):
import java.util.*;
class Solution {
public int[] findDiagonalOrder(List<List<Integer>> nums) {
List<int[]> arr = new ArrayList<>();
for (int i = 0; i < nums.size(); ++i) {
for (int j = 0; j < nums.get(i).size(); ++j) {
arr.add(new int[] {i + j, j, nums.get(i).get(j)});
}
}
Collections.sort(arr, (a, b) -> {
if (a[0] != b[0]) return a[0] - b[0];
return a[1] - b[1];
});
int[] ans = new int[arr.size()];
for (int i = 0; i < arr.size(); ++i) {
ans[i] = arr.get(i)[2];
}
return ans;
}
}
The other languages (C++, Go, TypeScript, C#) follow a similar pattern, creating tuples/arrays, sorting them, and extracting the result. The core logic remains the same across all implementations.