1. 程式人生 > >手撕程式碼:從遞迴的輔助空間的創新,助廣大學子喜提offer

手撕程式碼:從遞迴的輔助空間的創新,助廣大學子喜提offer

文章目錄

前情概要:

這是一個面試階段的手撕程式碼問題。可能是出題沒有太深究,面試官的標準答案是遞迴,某位優秀的師兄拍拍腦瓜想出了輔助空間的做法,大大降低了時間和空間複雜度。贏得了眾多面試官的一致好評,差點當場簽約。

題目描述:

現有N個球,分別按照順序標號:1~N;現在要求去除部分球,要求如下:

  1. 去除所有標號為(1、22、32、42、52…)完全平方數的球體;
  2. 將剩餘的K個球體重新編號為1~K;
  3. 重複上述過程,直到只留下最後一個球;
樣例輸入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; } } } }