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

    思路1:环形链表,每次只删除一个数,都从第0个开始。每次都从链表重复遍历,每删除一个,走m步,共n遍

    时间O(nm),空间o(n)

    import java.util.*;
    public class Solution {
        public int LastRemaining_Solution(int n, int m) {
            if(n < 1 || m < 1) {
                return -1;
            }
            List<Integer> list =  new LinkedList<>();
            for (int i = 0; i < n; i++) {
                list.add(i);
            }
            int idx = 0;
            while(list.size() > 1) {
                // 只要移动m-1次就可以移动到下一个要删除的元素上
                for (int i = 1; i < m; i++) {
                    idx = (idx + 1) % list.size();//保证删除后,当数组数量小于m时,仍能正确的去删除
                }
                list.remove(idx);
            }
            
            return  list.get(0);
        }
        
    }
    View Code

    思路2:时间O(n),空间o(1),

    f(n,m) = f '(n - 1, m) {删除一个数后,再每次去删除第m个,最后剩下的数  ,一定等于, 上一次操作中,再每次去删除第m个,最后剩下的数}

    即,不管处于第几次删除第m个数的循环里,最后剩下的数是一样的。

    f(n,m) = {0,n=1(f(n,m)表示在n个数中,每次删除第m个后,最后剩下的一个数)

        [f(n -1,m) + m] % n, n > 1 

    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;
        }
    }
    View Code

     测试:输入m小于n,输入的m大于n,特殊输入;圆圈有0个数;性能从4000个数删除997

  • 相关阅读:
    servlet
    反射
    网络通信协议
    线程安全,
    线程池, Callable<V>接口
    Thread类,Runnable 接口
    commons-IO
    序列化流与反序列化流,打印流
    转换流,Properties 集合
    缓冲流
  • 原文地址:https://www.cnblogs.com/lingli-meng/p/7102691.html
Copyright © 2011-2022 走看看