打印出大小为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/
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/
相关文章推荐
- 找出一个字符数组(元素不重复)所有可能字符的组合
- 按要求打印字符数组中所有可能的字符组合
- 排列组合-打印出一个数组的元素的所有排列方式-算法
- 给定一个数组,求数组中所有元素的可能组合(每个元素只出现一次),使其和等于给定数的解决办法
- 给定一个数组,n个数,打印所有可能的r位数的组合。例如{1,2,3,4}n=4,r=2.输出{1,2}{1,3}{1,4}{2,3}{2,4}{3,4}
- 递归列举从数组b()中选出某些元素(允许重复)使其和等于num的所有组合
- 给一个字符串(包含重复字符),打印它的所有可能的组合。
- 9.10扩展性与存储限制(三)——若只有4KB内存可用,该如何打印数组中所有重复的元素
- 打印一个含有重复元素数组的所有子集
- 给定一个数组,求数组中所有元素的可能组合(每个元素只出现一次),使其和等于给定数的解决办法
- 若只有4KB内存可用,该如何打印数组中所有重复的元素
- 递归列举从数组b()中选出某些元素(允许重复)使其和等于num的所有组合
- 程序员面试题目总结--数组(一)【递归求数组所有元素和、用一个for循环打印出一个二维数组、用递归判断数组是否是递增、有序数组中删除重复元素】
- 打印数组中所有重复的元素
- 编写程序从标准输入设备读入的元素数据建立一个int型vector对象,然后动态创建与该vector大小一致的数组,把vector对象的所有元素复制给该数组
- 从n个数组中任意选取一个元素的所有组合的Java实现(组合问题)
- 找出数组中重复次数最多的元素并打印
- 动态创建一个与该 vector 对象大小一致的数组,把 vector 对象的所有元素复制给新数组_初学vector对象4
- 从数组中取出n个元素的所有组合(递归实现)
- 把vector对象所有元素复制给动态建立的与之大小相同的数组