题目:带重复元素的排列



给出一个具有重复数字的列表,找出列表所有不同的排列

您在真实的面试中是否遇到过这个题?

Yes





样例

给出列表[1,2,2],不同的排列有:

[

    [1,2,2],

    [2,1,2],

    [2,2,1]

]

挑战

能否不使用递归完成?

标签 Expand   



相关题目 Expand   


解题思路:
     /*
      * 将所有的排列保存在list中 利用交换的思想,
      * 先,求所有可能出现在第一个位置的字符,
      *
      * 其次,把第一个字符和其后面的字符一一交换。如下图所示,分别把第一个字符a和后面的b、c等字符交换的情形。
      *
      * 接着,固定第一个字符,求后面所有字符的排列。这个时候我们仍把后面的所有字符分成两部分:后面字符的第一个字符,以及这个字符之后的所有字符。
      * 然后把第一个字符逐一和它后面的字符交换
      */在将nums加入时候,需要做个判断是否已经存在。
class Solution {
    /**
     * @param nums: A list of integers.
     * @return: A list of unique permutations.
     */
    public ArrayList<ArrayList<Integer>> permuteUnique(ArrayList<Integer> nums) {
        // write your code here
        ArrayList<ArrayList<Integer>> res = new ArrayList<>();
          ArrayList<Integer> item = new ArrayList<>();
          permuteUnique(nums, res, 0, nums.size()-1);
          return res;

     }
      @SuppressWarnings("unchecked")
     public void permuteUnique(ArrayList<Integer> nums,
               ArrayList<ArrayList<Integer>> res, int s, int e) {
          if (s == e) { // s=e 则将其加入res中
               boolean flag = false; // res中是否存在tmp值的arraylist.
               for (int i = 0; i < res.size(); i++) {
                    if (res.get(i).equals(nums)) {
                         flag = true;
                         break;
                    }
               }
               if (!flag) {
                    res.add((ArrayList<Integer>) nums.clone());
               }
               return;
          } else {
               for (int i = s; i < nums.size(); i++) {
                    swap(nums, s, i);
                    permuteUnique(nums, res, s + 1, e);
                    swap(nums, s, i);
               }
          }
     }

     public void swap(ArrayList<Integer> nums, int s, int e) {
          int tmp1 = nums.get(s);
          int tmp2 = nums.get(e);
          nums.set(s, tmp2);
          nums.set(e, tmp1);
    }
}






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值