題目
小明最近在研究壓縮算法。
他知道,壓縮的時候如果能夠使得數值很小,就能通過熵編碼得到較高的壓縮比。
然而,要使數值很小是一個挑戰。
最近,小明需要壓縮一些正整數的序列,這些序列的特點是,後面出現的數字很大可能是剛出現過不久的數字。對於這種特殊的序列,小明準備對序列做一個變換來減小數字的值。
變換的過程如下:
從左到右枚舉序列,每枚舉到一個數字,如果這個數字沒有出現過,剛將數字變換成它的相反數,如果數字出現過,則看它在原序列中最後的一次出現後面(且在當前數前面)出現了幾種數字,用這個種類數替換原來的數字。
比如,序列(a1, a2, a3, a4, a5)=(1, 2, 2, 1, 2)在變換過程爲:
a1: 1未出現過,所以a1變爲-1;
a2: 2未出現過,所以a2變爲-2;
a3: 2出現過,最後一次爲原序列的a2,在a2後、a3前有0種數字,所以a3變爲0;
a4: 1出現過,最後一次爲原序列的a1,在a1後、a4前有1種數字,所以a4變爲1;
a5: 2出現過,最後一次爲原序列的a3,在a3後、a5前有1種數字,所以a5變爲1。
現在,給出原序列,請問,按這種變換規則變換後的序列是什麼。
輸入格式:
輸入第一行包含一個整數n,表示序列的長度。
第二行包含n個正整數,表示輸入序列。
輸出格式:
輸出一行,包含n個數,表示變換後的序列。
思路
HashSet不允許集合中有重複的值,所以用它存儲
代碼
import java.util.*;
public class Main{
static int[] a,b;
public static void main(String [] args){
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){//相當於!=EOF
int n = sc.nextInt();
a = new int[n+5];
b = new int[n+5];
for(int i = 0; i < n; ++i)
a[i] = sc.nextInt();
for(int i = 0; i < n; ++i)
b[i] = solve(i);
for(int i = 0; i < n-1; ++i)
System.out.print(b[i]+" ");
System.out.println(b[n-1]);
}
}
static int solve(int n){
int tmp = a[n];
HashSet<Integer> hashset = new HashSet<Integer>();
for(int i = n-1; i >= 0; --i){
if(a[i] == tmp){
return hashset.size();
}
hashset.add(a[i]);
}
return (-1)*tmp;
}
}