手撕代码:从递归到辅助空间的创新,助广大学子喜提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;

            }
        }

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值