题目如下
注意画线地方排序要求。
我的答案
先展示我的答案:
总体思路:
递归+回溯(不会的可以去看力扣或者牛客网的解析,篇幅比较长不在此过多赘述)
将数组转为集合然后进行传参(方便使用集合中的Collections.swap()进行处理)
递归终止条件:当begin>=end时递归结束返回。
for循环中依次递归然后回溯。
两个易错点:
易错点一:32行标记的地方容易直接写成ll.add(list);
运行结果就成了这样
原因:直接将list添加到ll中,会导致后面再次进入递归进行集合中元素交换操作的时候 已经添加到ll中的list集合也跟着发生改变(引用传递)
具体是怎么个过程呢,通过调试可知:
第一次添加执行ll.add(list)时list集合中是123
再往下执行到i++即i=2时
再往下执行
会发现,诶? 不仅list中元素交换了,ll中保存的list也跟着交换了,这就是问题所在
所以当再次添加时,ll集合中添加的两个集合都是一样的132了,也就导致最后都变为了123 123的集合。
易错点二:题目要求中的按字典序排序输出
来看看直接使用ArrayList会发生什么:
可以看出,实际输出的排序顺序不对。
解决办法:
由于要按每个集合内的元素依次进行比较来排序,故可以使用TreeSet数据结构,使用自定义比较器规则,依次取出TreeSet中保存的集合来进行比较,通过for循环对两个集合中的元素一一判断返回。
个人解题思路,与官方答案不一致,仅供参考
相关练习题:牛客网 BM56 有重复项数字的全排列