手撕程式碼:從遞迴的輔助空間的創新,助廣大學子喜提offer
阿新 • • 發佈:2018-12-11
文章目錄
前情概要:
這是一個面試階段的手撕程式碼問題
。可能是出題沒有太深究,面試官的標準答案是遞迴
,某位優秀的師兄拍拍腦瓜想出了輔助空間
的做法,大大降低了時間和空間複雜度。贏得了眾多面試官的一致好評,差點當場簽約。
題目描述:
現有N個球,分別按照順序標號:1~N;現在要求去除部分球,要求如下:
- 去除所有標號為(1、22、32、42、52…)完全平方數的球體;
- 將剩餘的K個球體重新編號為1~K;
- 重複上述過程,直到只留下最後一個球;
樣例輸入input
6
樣例輸出output
5
題目分析及程式碼實現
題目分析 這是一個面試題目,手撕程式碼系列,常規思路為遞迴操作,但是使用輔助空間的話可以很大的節省時間和空間資源 定義一個初始陣列和遊標陣列,遊標陣列初始化為全1,不符合的遊標陣列值置為0。
小球陣列[1,2,3,4,5,6]
遊標陣列[1,1,1,1,1,1] (1)
遊標陣列[0,1,1,0,1,1] (2)
遊標陣列[0,0,1,0,1,0] (3)
遊標陣列[0,0,0,0,1,0] (4)
輸出編號5
這裡是使用了一個輔助空間,因為只需要輸出一開始的編號,也就是最初陣列中的值,故也可以直接將原陣列不符合標準的置為零 在每一輪判斷編號的時候原陣列為零不加,不為零加一,也可以有同樣的效果。這樣沒有空間的額外申請,但是破壞了原陣列。在本題中沒有影響,如遇到變種可以酌情變通。
程式碼實現
import java.util.Scanner;
public class delete_the_ball {
public static void main(String []args){
Scanner in =new Scanner(System.in);
int N;//球的個數
double sum=0;//記錄每一輪的序號值
int where=0;//記錄位置
N =in.nextInt();
int input[] = new int[N+1];
int temp[] = new int[N+1];
//按序初始化小球陣列
for(int i=1;i<= N;i++)
input[i]=i;
//按序初始化遊標陣列
for(int i=1;i<=N;i++)
temp[i]=1;
Loop: while (true){
//每一次進入迴圈都做一次累加,判斷是否只剩一個
for (int i=1;i<=N;i++){
sum+=temp[i];
//每一次都記錄遊標等於1的值,當只剩一個時,自然是目標小球的下標
if (temp[i]==1)
where=i;
}
//當遊標陣列的累加值為1時,輸出結果
if(sum==1){
System.out.println(where);
break Loop;
}
//將每一輪統計前將遊標總數置為零
sum=0;
for(int i=1;i<=N;i++){
sum+=temp[i];
//將sum開平方對1取餘操作
if (Math.sqrt(sum)%1==0)
temp[i]=0;
}
}
}
}