这两天琢磨这个算法, 终于有了结果. 下面以 8 个元素中取4个为例子
需要两个结构 stacks 和 remains, 他们是列表并需要排序, 先开始元素放置如下
stacks
1 | 2 | 3 | 4 |
5 | 6 | 6 | 8 |
remains
最简单的情况,把stacks和 remains刚好大于它的元素交换,就得到下个需要的数
stacks
1 | 2 | 3 | 5 |
4 | 6 | 6 | 8 |
remains
下面看复杂的情况, 8 在 remains 中不可能找到比它大的元素
1 | 2 | 3 | 8 |
4 | 5 | 6 | 7 |
所以先把8放到 remains 的尾部
1 | 2 | 3 |
4 | 5 | 6 | 7 | 8 |
而后安常规方法处理元素3
1 | 2 | 4 |
3 | 5 | 6 | 7 | 8 |
因为需要4个元素的子集合, 再把remains的头元素,添加到 stacks中
1 | 2 | 4 | 3 |
5 | 6 | 7 | 8 |
package com.pnp.findnextnumber;
import java.util.ArrayList;
import java.util.Collections;
public class Main {
ArrayList<Integer> remains = new ArrayList<Integer>();
ArrayList<Integer> stacks = new ArrayList<Integer>();
int TOTAL_COUNT = 10;
int SELECT_COUNT = 4;
void init() {
for( int i=0; i<TOTAL_COUNT; i++)
remains.add(i+1);
Collections.sort(remains);
for (int i=0; i<SELECT_COUNT; i++)
stacks.add( remains.remove(0));
}
void selectNext() {
while (stacks.size() > 0) {
int max_in_stack = stacks.remove(stacks.size() -1);
int pos = Collections.binarySearch(remains, max_in_stack);
//System.out.println(" max_in_stack:" + max_in_stack + " pos:" + pos);
if (pos < 0) // binarySearch return -( insertion pos)
pos = (-pos) -1;
if (pos == remains.size()) {// max_in_stack is large than any one in remains
remains.add( max_in_stack ); //remove last elements
}
else {
// xchange element
stacks.add(remains.get(pos));
remains.set(pos, max_in_stack);
// add more untill reach SELECT_COUNT
while ( stacks.size() < SELECT_COUNT) {
stacks.add(remains.remove(0));
}
System.out.print(" an select ---");
print(stacks);
return;
}
}
}
void selectAll() {
while (stacks.size() > 0)
selectNext();
}
static void print(ArrayList<Integer> list ) {
for (int i=0; i< list.size(); i++)
System.out.print( " " + list.get(i));
System.out.println();
}
public static void main(String[] args) {
Main m = new Main();
m.init();
m.selectAll();
}
}