您的位置:首页 > 其它

打印出大小为n的数组(可能有重复元素)里所有可能的组合

2014-07-05 09:17 363 查看
Input: {1, 2, 3, 4}, r=2 Output: {1, 2}, {1, 3}, {1, 4}, {2, 3}, {2, 4} and {3, 4}.

package recursion;

import java.util.ArrayList;
import java.util.Collections;

public class Print_all_possible_combinations_of_r_elements_in_a_given_array_of_size_n {

/*
Input:
{1, 2, 3, 4}, r=2
Output:
{1, 2}, {1, 3}, {1, 4}, {2, 3}, {2, 4} and {3, 4}.

*/
public static void main(String[] args) {
int[] s1 = {1, 2, 3, 4};
ArrayList<Integer> set1 = new ArrayList<Integer>();
for (int i : s1) {
set1.add(i);
}
int r1 = 2;
ArrayList<ArrayList<Integer>> ret1 = new ArrayList<ArrayList<Integer>>();
rec2(set1, r1, 0, ret1, new ArrayList<Integer>());
System.out.println(ret1);

int[] s2 = {1, 2, 1, 3, 2};
ArrayList<Integer> set2 = new ArrayList<Integer>();
for (int i : s2) {
set2.add(i);
}
int r2 = 2;
ArrayList<ArrayList<Integer>> ret2 = new ArrayList<ArrayList<Integer>>();

Collections.sort(set2);
rec2(set2, r2, 0, ret2, new ArrayList<Integer>());
System.out.println(ret2);
}

// 解法一:分析:观察output可得,先循环选定添加到al的第一个元素,然后缩小子区间,递归处理子问题
// first是当前处理子区间的第一个元素
public static void rec(ArrayList<Integer> set, int r, int first, ArrayList<ArrayList<Integer>> ret, ArrayList<Integer> al) {
if(al.size() == r) { // 退出条件:当al里的数量达到r时即可退出
ret.add(new ArrayList<Integer>(al));
return;
}

for(int i=first; i<set.size(); i++) { // 从子区间的第一个元素到最后一个元素都有机会被添加到al中
if(i+1<set.size() && set.get(i+1) == set.get(i)) { // 跳过重复元素,但要检查是否越界
continue;
}
al.add(set.get(i)); // 注意在for循环内,用到的参数是i而不是first
rec(set, r, i+1, ret, al); // 缩短子区间1个距离
al.remove(al.size()-1);
}
}

// 解法二:选择或者不选择某个元素
public static void rec2(ArrayList<Integer> set, int r, int first, ArrayList<ArrayList<Integer>> ret, ArrayList<Integer> al) {
if(r == al.size()) { // 退出条件:当al里的数量达到r时即可退出
ret.add(new ArrayList<Integer>(al));
return;
}

if(first >= set.size()) { // 当first遍历超过set容量时也要返回
return;
}

while(first+1<set.size() && set.get(first+1) == set.get(first)) { // 跳过重复元素,但要检查是否越界
first++;
}

rec2(set, r, first+1, ret, al); // 不选择当前元素

al.add(set.get(first)); // 选择当前元素
rec2(set, r, first+1, ret, al);
al.remove(al.size()-1);
}

}

http://www.geeksforgeeks.org/print-all-possible-combinations-of-r-elements-in-a-given-array-of-size-n/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐