Hashing - Hard Version

Given a hash table of size NNN, we can define a hash function . Suppose that the linear probing is used to solve collisions, we can easily obtain the status of the hash table with a given sequence of input numbers.

However, now you are asked to solve the reversed problem: reconstruct the input sequence from the given status of the hash table. Whenever there are multiple choices, the smallest number is always taken.

Input Specification:

Each input file contains one test case. For each test case, the first line contains a positive integer NNN (≤1000\le 10001000), which is the size of the hash table. The next line contains NNN integers, separated by a space. A negative integer represents an empty cell in the hash table. It is guaranteed that all the non-negative integers are distinct in the table.

Output Specification:

For each test case, print a line that contains the input sequence, with the numbers separated by a space. Notice that there must be no extra space at the end of each line.

Sample Input:

11
33 1 13 12 34 38 27 22 32 -1 21

Sample Output:

1 13 12 21 33 34 38 27 22 32


思路:我用的是TreeMap保存数据,每次从顶端拿出一个最小的来

package HashingHardVersion;
import java.util.*;
import java.util.Map.Entry;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] a = new int[n];
        for(int i=0; i<n; i++)	a[i] = sc.nextInt();
        
        boolean[] marked = new boolean[n];
        boolean[] added = new boolean[n];
        TreeMap<Integer, Integer> map = new TreeMap<Integer, Integer>();
        for(int i=0; i<n; i++) 
        	if(a[i] != -1 && a[i] % n == i) {
        		added[i] = true;
        		map.put(a[i], i);
        	}
        
        StringBuilder sb = new StringBuilder();
        while(!map.isEmpty()) {
        	Entry<Integer, Integer> next = map.pollFirstEntry();
        	marked[next.getValue()] = true;
        	sb.append(next.getKey() + " ");
        	
        	for(int i=0; i<n; i++) {
        		if(a[i] != -1 && !added[i]) {
        			if(canReach(a, marked, a[i] % n, i, n)) {
        				added[i] = true;
        				map.put(a[i], i);
        			}
        		}
        	}
        }
        
        System.out.println(sb.toString().trim());
	}

	private static boolean canReach(int[] a, boolean[] marked, int s, int t, int n) {
		for(int i=s; i<t+n; i++)	
			if(i%n == t)	return true;
			else if(a[i%n] == -1 || !marked[i%n])	return false;
		return true;
	}

}

仔细分析一下会发现这其实就是 拓扑排序!!



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值