zoukankan      html  css  js  c++  java
  • 约瑟夫问题

    LeetCode 剑指offer62

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

    这个问题是以弗拉维奥·约瑟夫命名的,他是1世纪的一名犹太历史学家。他在自己的日记中写道,他和他的40个战友被罗马军队包围在洞中。他们讨论是自杀还是被俘,最终决定自杀,并以抽签的方式决定谁杀掉谁。约瑟夫斯和另外一个人是最后两个留下的人。约瑟夫斯说服了那个人,他们将向罗马军队投降,不再自杀。约瑟夫斯把他的存活归因于运气或天意,他不知道是哪一个。 —— 【约瑟夫问题】维基百科

    一、模拟单向环形链表

    据题解大佬所言,LinkedList会超时,因为链表remove中删除复杂度为1,但查找到该索引需n;ArrayList相反是查找为1,删除为n。不过因为ArrayList删除是拷贝的后面元素是连续地址的,而链表需要大量访问非来纳许地址,因此耗时。

    复杂度为O(n2)

    class Solution {
        public int lastRemaining(int n, int m) {
            ArrayList<Integer> list = new ArrayList<>(n);
            for (int i = 0; i < n; i++) {
                list.add(i);
            }
            int idx = 0;
            while (n > 1) {
                idx = (idx + m - 1) % n;
                list.remove(idx);  // 注意remove后idx自动后移
                n--;
            }
            return list.get(0);
        }
    }

    二、数学解法

    f(n,m)与f(n-1,m)之间的关系:当n个数先删掉第一个坐标(m-1)%n时,可以看成n-1个数组成的环,其中首元素坐标为m。而f(n-1,m)的首元素坐标为0,因此 f(n,m) = ( f(n-1,m) + m ) % n。

    class Solution {
        public int lastRemaining(int n, int m) {
            int ans = 0;
            // 最后一轮剩下2个人,所以从2开始反推
            for (int i = 2; i <= n; i++) {
                ans = (ans + m) % i;
            }
            return ans;
        }
    }

    三、马拉车算法 Manacher's algorithm

    参考链接

    构造T,在每个字符两边添加‘#’,n+(n+1)统一成奇回文。 构造P对应以T中每个字符为中心的回文长度,寻找最大值。

    1、最大半径减1等于最长回文串的长度

    2、最长回文字符的起始位置(s中的索引)是中间位置(T或P中的索引)减去半径(P中的值+1)再除以2

    这里的P为回文长度,因此无需与半径做转换。

    public class Solution {
     2     // Transform S into T.
     3     // For example, S = "abba", T = "^#a#b#b#a#$".
     4     // ^ and $ signs are sentinels appended to each end to avoid bounds checking
     5     String preProcess(String s) {
     6         int n = s.length();
     7         if (n == 0) return "^$";
     8 
     9         String ret = "^";
    10         for (int i = 0; i < n; i++)
    11         {
    12             ret += "#" + s.substring(i, i + 1);
    13         }
    14         
    15         ret += "#$";
    16         return ret;
    17     }
    18     public String longestPalindrome(String s) {
    19         String T = preProcess(s);
    20         int length = T.length();
    21         int[] p = new int[length];
    22         int C = 0, R = 0;
    23         
    24         for (int i = 1; i < length - 1; i++)
    25         {
    26             int i_mirror = C - (i - C);
    27             int diff = R - i;
    28             if (diff >= 0)//当前i在C和R之间,可以利用回文的对称属性
    29             {
    30                 if (p[i_mirror] < diff)//i的对称点的回文长度在C的大回文范围内部
    31                 { p[i] = p[i_mirror]; }
    32                 else
    33                 {
    34                     p[i] = diff;
    35                     //i处的回文可能超出C的大回文范围了
    36                     while (T.charAt(i + p[i] + 1) == T.charAt(i - p[i] - 1))
    37                     { p[i]++; }
    38                     C = i;
    39                     R = i + p[i];
    40                 }
    41             }
    42             else
    43             {
    44                 p[i] = 0;
    45                 while (T.charAt(i + p[i] + 1) == T.charAt(i - p[i] - 1))
    46                 { p[i]++; }
    47                 C = i;
    48                 R = i + p[i];
    49             }
    50         }
    51 
    52         int maxLen = 0;
    53         int centerIndex = 0;
    54         for (int i = 1; i < length - 1; i++) {
    55             if (p[i] > maxLen) {
    56               maxLen = p[i];
    57               centerIndex = i;
    58             }
    59         }
    60         return s.substring((centerIndex - 1 - maxLen) / 2, (centerIndex - 1 - maxLen) / 2 + maxLen);        
    61     }
    62 }
  • 相关阅读:
    HDU 6071
    HDU 6073
    HDU 2124 Repair the Wall(贪心)
    HDU 2037 今年暑假不AC(贪心)
    HDU 1257 最少拦截系统(贪心)
    HDU 1789 Doing Homework again(贪心)
    HDU 1009 FatMouse' Trade(贪心)
    HDU 2216 Game III(BFS)
    HDU 1509 Windows Message Queue(队列)
    HDU 1081 To The Max(动态规划)
  • 原文地址:https://www.cnblogs.com/faded828x/p/13449374.html
Copyright © 2011-2022 走看看