zoukankan      html  css  js  c++  java
  • 圆圈中最后剩下的数字

    题目描述:0,1,...,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字。求出这个圆圈里剩下的最后一个数字。

    思路分析:(一)这个问题类似于从链表中删除,而且是循环链表,所以可以通过链表来描述,但由于问题中涉及到编号,故还是采用ArrayList来刻画比较好。具体分为以下几步:

    1.判断不合法情况,即m和n都小于1;

    2.创建一个大小为n的ArrayList,并给它们赋初值0--n-1来刻画编号;

    3.当链表的大小大于1执行如下操作:每隔m删除一个,并且对应的索引点发生变化。

    (二)分析被删除数字的规律,找出规律,编写代码,具体分析如下:

    假设从0-n-1中删除了第m个数字,则下一轮的数字排列为m,m+1,.....n-1,0,1,2,3...m-2,将该数字排列重新映射为0~n-2,则为

    m    0

    m+1    1  

    ....    ....

    n-1   n-1-m

    0    n-m

    1    n-m+1

    ...    ....

    m-2    n-2

    可以看出从右往左的映射关系为left=(right+m)%n,即0~n-1序列中最后剩下的数字等于(0~n-2序列中最后剩下的数字+m)%n,很明显当n=1时,只有一个数,那么剩下的数字就是0.

    问题转化为动态规划问题,关系表示为:

    f(n)=(f(n-1)+m)%n; 当n=1,f(1)=0;

    代码实现

    (1)链表描述

    import java.util.ArrayList;
    public class Solution {
        public int LastRemaining_Solution(int n, int m) {
           if(n==0||m<1)
           {
               return -1;
           }
            ArrayList<Integer> list = new ArrayList<Integer>();
            for(int i=0;i<n;i++)
            {
                list.add(i);
            }
           int  index = -1;
            while(list.size()>1)
            {
                index = (index+m)%list.size();
                list.remove(index);
                index--;
            }
            return list.get(0);
        }
    }

    (2)递归公式

    import java.util.ArrayList;
    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;
        }
    }
  • 相关阅读:
    收集一些特殊的符号
    腾讯笔试有感
    Lazy Load, 延迟加载图片的 jQuery 插件
    腾讯实习生笔试题
    IE捉迷藏bug详解(躲猫猫)
    使用SQL Server 2000 全文检索
    一篇比较不错的关于masterpage的文章
    ASP.NET中对表单输入行有选择验证
    在WSS中高亮显示搜索结果
    WebPart安装位置对FrontPager的影响
  • 原文地址:https://www.cnblogs.com/Dream-chasingGirl/p/10295358.html
Copyright © 2011-2022 走看看