n个整数,分成数值连续的几组

本文介绍了一种将数组中的连续整数按原始顺序分组的高效算法。该算法首先通过哈希映射记录每个元素的位置,然后遍历数组,利用递归检查相邻元素并将其添加到对应的组中。最后对每个组进行排序并打印结果。算法的时间复杂度介于O(n)到O(n log n)之间,具体取决于数据分布。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

要求相对位置不变。


 * 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);
	}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值