剑指offer系列之45:圆圈中最后剩下的数字

题目描述:用0,1,…,n-1,这n个数字排成一个圆圈,从数字0开始每次从这个圆圈里删除第m个数字,求出这个圆圈里剩下的最后一个数字。(抽象建模能力)

思路1:经典的解法,用环形链表模拟圆圈,可以创建一个总共有n个节点的环形链表,然后每次在这个链表中删除第m个节点。

思路2:把这n个整数做成一个环,当数到哪个数的时候就把那个数移除,并从下一个数重新开始数。所已基本思路是:使用数组模拟环,当当前的元素的值n相等的时候,就回到第一个位置重新遍历,每次当前元素的移动都伴随计步器的增加(每次增加1),当步数等于m的时候,则把当前元素的设为-1,表示已被删除,并重新设置计步器的值为0,还需要把n的值减小1,表示数组中的元素被移除了一个。使用数组来模拟环。

public class LastRemainingNumber {


    public int LastRemaining_Solution2(int n, int m) {
        if (n < 1 || m < 1)
            return -1;
        int[] a = new int[n];
        //当前遇到的对象
        int cur = -1;
        //计步器
        int count = 0;
        int num = n;
        while (num > 0) {
            //移动到上次被删除元素的下一个元素
            cur++;
            //当遇到最后一个数的时候,从开头重新计算
            if(cur == n) cur = 0;
            //如果遇到了上次被删除的对象,则跳过该对象
            if(a[cur] == -1)
                continue;
            //计步器加1
            count++;
            if(count == m){
                //把当前元素标记为已删除
                a[cur] = -1;
                //计步器重新复位
                count = 0;
                num--;
            }
        }
        return cur;
    }
}

思路3:根据规律得到如下解法,参考剑指offer书上的解法。

public class Solution {
    public int LastRemaining_Solution(int n, int m) {
        if(n < 1 || m < 1){
            return -1;
        }
        int last = 0;
        for(int i = 2;i <= n;i++){
            last = (last+m)%i;
        }
        return last;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值