錯過了騰訊的春招編程題(在牛客筆試前已經電話面所以就沒參加,有自己做C++的筆試,對C++不熟,感覺已經涼了),但是朋友做了便截圖下來然後自己練習一下,給我的感覺就是,會做的就很快寫完,不會的基本沒有什麼思路,總之很快寫完了三道題,但是有兩道是不會的。下面按題目給出我的代碼,有錯的懇請指正。
1、
不要看到這個就以爲是揹包問題,這個是從大到小的,很簡單。。。
public static void lessCoins(){
String [] lines = scanner.nextLine().split(" ");
int n = Integer.parseInt(lines[0]),m = Integer.parseInt(lines[1]);
int count = 0,temp = 0;
while (m>0){
temp = n;
while (temp>m){
temp--;
}
m-=temp;
count++;
}
System.out.println(count);
}
2、
這個其實就是累加的意思,只是要對加數做個求餘判斷。
public static int getSum(int start,int end){
int sum = 0;
for (int i = start;i<=end;i++){
if(i%2==0) sum += i;
else sum -= i;
}
return sum;
}
int n = Integer.parseInt(scanner.nextLine());
int [][]res = new int[n][2];
int []r = new int[n];
String [] strs = null;
for (int i = 0;i<n;i++){
strs = scanner.nextLine().split(" ");
res[i][0] = Integer.parseInt(strs[0]);
res[i][1] = Integer.parseInt(strs[1]);
}
for (int i = 0;i<n;i++){
r[i] = getSum(res[i][0],res[i][1]);
System.out.println(r[i]);
}
3、
這題可能同學想到的,就是先枚舉所有排列,再和原來的數組做比較,得到結果相等時計數加1,當超過1e9+7時對計數取1e9+7的餘數,相信大部分人都這麼想,但是,這肯定是不可取的,17的階乘都超過了int的最大範圍,何況這裏有最多2000個數,那肯定是不可計算的。想一下,假設在相等的情況,有s個1,其他均爲0,那麼就有Cn的s種,而其他的還有2的(n-s)次方,因爲0、1、2,只能有2種可能是能贏的,而這些數也是有n-s個數,於是得到公式。所以代碼就很簡單了:
public static int calC(int n,int s){
int count = 1, e = n - s;
for (int i = s + 1;i<=n;i++){
count *=i;
if(count>1000000007)count%=1000000007;
}
while (e>0){
count *= 2;
if(count>1000000007)count%=1000000007;
e --;
}
return count;
}
因爲我沒有提交過題目,也不知道對不對,但是舉幾個例子都是沒有問題的,在s,n的範圍內也是算得很快,如果不對的請指正。
4、
看到這題,是不是感覺跟計算最長子串的思想有點那麼相似,如果你要這麼想,就往復雜裏面想了。相信學過計算機網絡的同學應該都聽說過滑動窗口,滑動窗口應該就是在傳送報文時可以動態更新的長度,窗口長度受對方主機反饋的影響。我覺得這個意思很像啊,說下我的思路,因爲要求所有顏色要命中,於是用一個list去裝這個序列,這個序列肯定都包含所有顏色但也可能有重複的顏色,因爲這個滑動窗口就是記錄原來數組中連續最少的槍數,此外我們還要判斷什麼這個list滿足包含所有顏色,當包含所有顏色時,就得到一個序列,這個滿足條件的序列長度就被保存下來到一個res_list中,到最後對res_list排序,取最前面的數就是最小的長度。那麼關鍵問題就是,滑動窗口怎麼設計,其實很簡單,因爲滑動窗口要滿足包含所有顏色,暫且用一個隊列來保存這個滑動窗口,只有當要入隊元素和隊首元素一樣時,我們纔對隊列操作,即隊首元素出隊,然後再入隊,這就能保證當前隊列不會有多餘的步長,當然,你非要說中間有相同的數,那我只能說沒有影響。當得到一個可用序列後,滑動窗口要更新的,就是刪除隊首,當隊首元素後有隊首元素時,刪除隊首元素直到沒有。於是代碼就出來了:
public static int lessShotCounts(int a[],int m){
ArrayList<Integer> res_list = new ArrayList<>();//所有滿足條件的窗口長度
ArrayList<Integer> list = new ArrayList<>();//得到一條路線的標誌
LinkedList<Integer> t_list = new LinkedList<>();//滑動窗口的數組
for(int i = 0;i<a.length;i++){
if(!list.contains(a[i])){
list.add(a[i]);
t_list.add(a[i]);
}
else{
if(t_list.get(0) == a[i]){
t_list.remove((Object)a[i]);
}
t_list.add(a[i]);
}
boolean flag = false;
if(list.contains(0) && list.size() == m + 1) flag = true;
if(!list.contains(0) && list.size() == m ) flag = true;
if(flag){
System.out.println(Arrays.toString(t_list.toArray()));
res_list.add(t_list.size());
if(t_list.get(0)!=null){
int temp = t_list.get(0);
t_list.remove((Object)temp);
list.remove((Object)temp);
if(t_list.get(0)!=null){
temp = t_list.get(0);
while (t_list.lastIndexOf(temp) !=0 && t_list.get(0)!=null){
t_list.remove((Object)temp);
temp = t_list.get(0);
}
}
}
}
}
if(res_list.size()==0)return -1;
else{
Collections.sort(res_list);
return res_list.get(0);
}
}
結果:
5、
這個題目我暫時還沒有頭緒,等我想到了再分享,或者有會的同學可以分享給我,十分感謝。