剑指offer62.圆圈中最后剩下的数字

这道题在算法课上的一个小故事上有一个类似的,就是一个军官打了败仗,带着他的几个兵逃到一个山洞,他们不想当俘虏想自杀,但是军官不想自杀但是又不好意思走,于是军官想了个办法,他们几个人围成一个圈,每次枪毙第5个,然后从下一个往下数5个,最后一个人自杀。只要军官站在第20个的位置上他就可以留到最后然后自己一个人走。

一开始想用循环链表,这样就可以按照题目的定义进行循环直到最后剩1个,但是用循环链表还得自己写结构体定义,最后就用了LinkedList,index表示从哪个位置开始算,delete表示要删除的位置,最后两个样例过了,其他示例超时了。

class Solution {
    public int lastRemaining(int n, int m) {
       LinkedList<Integer> num = new LinkedList<>();
       for(int i =0;i<n;i++){
          num.add(i);
       }
       int index = 0;
       while(num.size() != 1){
       int delete = index + m-1;
        int size = num.size();
       delete = delete % size;
         num.remove(delete);
         index=delete;
       }
       return num.peek();
    }
}

 然后自己又想了一会,没思路,就直接看题解了,题解这个递归都让我看了将近20分钟才看懂,但是看懂了就觉得好简单,没看懂就一直理解不了。

定义一个递归函数f(int n, int m),他的返回值是一个int表示最后留下的是最后留下的元素的序号,对于一个长度为n的序列,我们第一次先删除m%n个元素,然后递归的求解出剩下的n-1个元素最后会剩下的那个元素的序号,记为x,int x = f(n-1, m);

也就是说当我们删除n个元素中第m%n个元素后,剩下的n-1个元素如果从第1个开始算,最后会剩下第x个元素,但是我们不是从第1个开始算的,我们是从第m%n个元素开始算的,所以最后剩下的是第m%n+x个元素,以防越界,最后再%n,也就是第(m%n+x)%n个元素,递归必须有终止条件,这道题的终止条件就是当n等于1的时候,返回第0个元素。

class Solution {
    public int lastRemaining(int n, int m) {
        return f(n, m);
    }
    public int f(int n, int m){
        if(n == 1){
            return 0;
        }
        int x = f(n-1, m);
        return (m%n + x) % n;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

荔枝味啊~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值