leetcode
leetcode 2301 ~ 2350
转换二维数组

转换二维数组

难度:

标签:

题目描述

You are given an integer array nums. You need to create a 2D array from nums satisfying the following conditions:

  • The 2D array should contain only the elements of the array nums.
  • Each row in the 2D array contains distinct integers.
  • The number of rows in the 2D array should be minimal.

Return the resulting array. If there are multiple answers, return any of them.

Note that the 2D array can have a different number of elements on each row.

 

Example 1:

Input: nums = [1,3,4,1,2,3,1]
Output: [[1,3,4,2],[1,3],[1]]
Explanation: We can create a 2D array that contains the following rows:
- 1,3,4,2
- 1,3
- 1
All elements of nums were used, and each row of the 2D array contains distinct integers, so it is a valid answer.
It can be shown that we cannot have less than 3 rows in a valid array.

Example 2:

Input: nums = [1,2,3,4]
Output: [[4,3,2,1]]
Explanation: All elements of the array are distinct, so we can keep all of them in the first row of the 2D array.

 

Constraints:

  • 1 <= nums.length <= 200
  • 1 <= nums[i] <= nums.length

代码结果

运行时间: 32 ms, 内存: 16.1 MB


/*
 * 思路:
 * 1. 使用流的特性来简化代码。
 * 2. 首先将数组转换为Set集合,去重并生成第一个结果行。
 * 3. 通过移除已处理的元素,继续生成剩余的行。
 */

import java.util.*;
import java.util.stream.Collectors;

public class Solution {
    public List<List<Integer>> findMatrix(int[] nums) {
        List<List<Integer>> result = new ArrayList<>();
        Set<Integer> used = Arrays.stream(nums).boxed().collect(Collectors.toSet());
        while (!used.isEmpty()) {
            Set<Integer> rowSet = new HashSet<>();
            List<Integer> row = Arrays.stream(nums)
                                      .boxed()
                                      .filter(num -> used.contains(num) && rowSet.add(num))
                                      .collect(Collectors.toList());
            result.add(row);
            row.forEach(used::remove);
        }
        return result;
    }
}

解释

方法:

此题解主要利用了哈希表来记录每个数字出现的次数,并通过构造多个行数组来保证每一行的数字都是不同的。首先,使用Counter或字典统计每个数字出现的次数。然后,基于数字出现的次数,为每个数字在不同的行中分配位置。如果一个数字出现n次,则它将尝试放在前n行中的每一行。这样,可以确保二维数组的行数尽可能少,并且每一行的数字都是不同的。

时间复杂度:

O(n*m)

空间复杂度:

O(n + u)

代码细节讲解

🦆
在算法中,为什么首先选择使用哈希表来记录每个数字的出现次数?
哈希表(例如 Python 中的字典或 Counter)在算法中用于记录每个数字的出现次数,因为它可以在常数时间内完成插入和查找操作,这使得统计每个元素的频率变得非常高效。此外,哈希表还可以方便地访问任何具体数字的计数,这对于后续的数字分配和检查是否已将某数字放入特定行中非常关键。
🦆
算法是如何确保每一行中的数字都是唯一的?
算法通过在放置数字之前检查该数字是否已存在于当前行来确保每行中的数字都是唯一的。在第一种解法中,每个数字尝试按其出现次数顺序被添加到不同的行中,行中已有数字会使用集合来去重。在第二种解法中,通过在添加前检查行中是否已包含该数字来直接防止重复。如果行中已存在该数字,则搜索下一行或创建新行。
🦆
当数字的出现次数非常高时,算法的性能是否会受到影响?如果会,为什么?
当数字的出现次数非常高时,算法的性能确实会受到影响。首先,需要更多的行来放置重复频次高的数字,这增加了行数组的大小和处理时间。其次,特别是在第二种解法中,每次放置数字时都需要检查多行以确认数字是否已存在,这会导致更多的行检查操作,从而增加时间复杂度。因此,数字频次的增加直接影响到行的管理和搜索时间,尤其是在行数较多时。
🦆
在处理数字时,为什么需要检查并尝试将数字放置在已有的所有行中?是否有更高效的方法来避免反复的行检查?
在处理数字时,需要检查并尝试将数字放置在已有的所有行中,以确保不违反每行数字唯一性的约束。这种方法虽然可行,但不是最高效的。一个更高效的方法可能是使用额外的数据结构,如哈希表或位图,来追踪每行已经包含哪些数字。这样,可以在常数时间内检查数字是否已在行中,从而减少不必要的行检查。另外,维护一个指针数组,指向每行的下一个可放置位置,也可以提高效率,避免每次都从头扫描每行。

相关问题