小学生都能看懂的题解 | #有重复项数字的全排列#

有重复项数字的全排列

https://www.nowcoder.com/practice/a43a2b986ef34843ac4fdd9159b69863

解题思路:

  1. 排序:首先,我们要把数字数组按从小到大的顺序排好。这样可以帮助我们在寻找不同排列的时候,更容易发现重复的情况。
  2. 递归:然后,我们使用一种叫做“递归”的方法来帮助我们找到所有的排列。就像搭积木一样,我们一步一步地把数字放进去,直到所有的位置都填满了。
  3. 记录已使用的数字:为了避免重复使用同一个位置上的数字,我们需要记住哪些数字已经被放在排列里了。
  4. 跳过重复的数字:如果当前要放置的位置上,出现了和前面位置上一样的数字,而且前面的位置还没有被使用过,那么我们就跳过这个数字,因为这样做可以避免产生重复的排列。

示例代码:

让我们写一段简单的 Java 代码来实现这个想法:

import java.util.ArrayList;

public class Solution {
    // 方法名改为permuteUnique,并且返回类型为ArrayList<ArrayList<Integer>>
    public ArrayList<ArrayList<Integer>> permuteUnique(int[] numbers) {
        ArrayList<ArrayList<Integer>> allPermutations = new ArrayList<>();
        
        // 首先对数组进行排序
        Arrays.sort(numbers);

        // 创建一个标记数组,用来记住哪些数字已经被使用了
        boolean[] used = new boolean[numbers.length];

        // 调用递归函数开始构建排列
        backtrack(allPermutations, new ArrayList<>(), numbers, used);

        return allPermutations;
    }

    // 递归函数
    private void backtrack(ArrayList<ArrayList<Integer>> allPermutations,
                           ArrayList<Integer> currentPermutation,
                           int[] numbers,
                           boolean[] used) {
        // 如果当前排列的长度等于数字的数量,说明已经完成了一个排列
        if (currentPermutation.size() == numbers.length) {
            allPermutations.add(new ArrayList<>(currentPermutation));
        } else {
            // 遍历每一个数字
            for (int i = 0; i < numbers.length; i++) {
                // 如果这个数字已经被使用过了,就跳过
                if (used[i]) continue;

                // 如果当前数字和前一个数字相同,并且前一个数字还没被使用,也跳过
                if (i > 0 && numbers[i] == numbers[i - 1] && !used[i - 1]) continue;

                // 把当前数字加入到当前排列中
                currentPermutation.add(numbers[i]);

                // 标记这个数字已经被使用过了
                used[i] = true;

                // 递归调用自己,继续构建下一个数字的排列
                backtrack(allPermutations, currentPermutation, numbers, used);

                // 回溯:移除当前数字,准备下一次循环
                currentPermutation.remove(currentPermutation.size() - 1);
                used[i] = false;
            }
        }
    }

}

如果这篇文章对你有帮助,请点个免费的赞👍,让它能够帮助更多的人。

#题解#
小学生都能看懂的算法 文章被收录于专栏

主要面向小白的算法文章。以小学生都能看懂为目标而编写,顺便巩固下自己。

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务