要求相对位置不变。
* Divide a list of numbers into group of consecutive numbers but their original order should be preserved?
* 8,2,4,7,1,0,3,6
* 2,4,1,0,3 and 8,7,6
* obviously in shortest time and space.
*
* 取决于链表局部排序时间,最差(只能分一组)O(nlgn),最好(一个一组)O(n)
public class GroupNumbers {
public HashMap<Integer, Element> map = new HashMap<Integer, Element>();
private ArrayList<Element> list = new ArrayList<Element>();
/**
* O(n)
* @param a
*/
public void makeHash(int[] a){
assert(true);
for(int i=0; i<a.length;i++){
Element e = new Element(a[i], i);
map.put(a[i], e);
}
}
public void divide(int[] a){
for(int i=0; i<a.length; i++){
if(a[i] == '$'){
continue;
}
work(a, i);
sort();
printList();
list.clear();
}
}
public void work(int[] a, int index){
Element e = map.get(a[index]);
list.add(e);
int v = a[index];
a[index] = '$';
check(a, v+1, true);
check(a, v-1, false);
}
private void printList(){
for(int i=0; i<list.size(); i++){
System.out.print(list.get(i).value + " ");
}
System.out.println();
}
private void sort(){
Collections.sort(list, new Comparator<Element>(){
@Override
public int compare(Element o1, Element o2) {
// TODO Auto-generated method stub
if(o1.p == o2.p){
return 0;
}else if(o1.p < o2.p){
return -1;
}else{
return 1;
}
}
});
}
private void check(int[] a, int v, boolean direction){
while(true){
Element e = map.get(v);
if(e == null){
break;
}
if(a[e.p] == '$'){
break;
}
list.add(e);
a[e.p] = '$';
if(direction){
v++;
}else{
v--;
}
}
}
public class Element{
int value;
int p;
public Element(int v, int i){
value = v;
p = i;
}
}
/**
* @param args
*/
public static void main(String[] args) {
int[] a = {8,2,4,7,1,0,3,6};
GroupNumbers gn = new GroupNumbers();
gn.makeHash(a);
gn.divide(a);
}
}