剑指Offer-面试题62:圆圈中最后剩下的数字-“约瑟夫环问题” ArrayList、数学解法(转载)

这里是题目描述:剑指Offer-面试题62:圆圈中最后剩下的数字

本题叫做 “约瑟夫环问题” 有两种解法:1.模拟执行整个删除数字的流程 2.以数学规律解题。这里是LeetCode官网中的两种解题方法详细描述

方法一:ArrayList模拟执行整个流程

从理论上分析,使用链表时确定删除数字的位置需要O(n),删除该数字需要O(1),一共需要执行n-1次删除;使用ArrayList确定删除数字的位置需要O(1),删除该数字需要O(n)(因为需要对被删除后面的数字移位),进行整个流程的模拟的时间复杂度都是O(n2),但是使用链表时会超出时间复杂度,使用ArrayList不会

class Solution {
    //基于ArrayList
    public int lastRemaining(int n, int m) {
        if(n==1)
        {
            return 0;
        }
        ArrayList<Integer> arrayList=new ArrayList<>();
        for(int i=0;i<n;i++)
        {
            arrayList.add(i);
        }
        int curIndex=0;
        while(arrayList.size()>1)
        {
            int delIndex=(curIndex+m-1)%arrayList.size(); //计算要移除的元素的下标
            arrayList.remove(delIndex); //移除
            curIndex=delIndex;
        }
        return arrayList.get(0);
    }
}

时间复杂度:O(n2)
空间复杂度:O(n)

方法二:使用数学方法解题
class Solution {
    //基于数学方法
    public int lastRemaining(int n, int m) {
        if(n==1)
        {
            return 0;
        }
        int ans=0; //最后剩余的元素下标肯定为0
        for(int l=2;l<=n;l++) //从要恢复的数组长度为2开始
        {
            ans=(ans+m)%l;
        }
        return ans;
    }
}

时间复杂度:O(n)
空间复杂度:O(1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值