【△重点△】剑指 Offer 62. 圆圈中最后剩下的数字——约瑟夫环问题

剑指 Offer 62. 圆圈中最后剩下的数字

题目描述

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

例如,0、1、2、3、4这5个数字组成一个圆圈,从数字0开始每次删除第3个数字,则删除的前4个数字依次是2、0、4、1,因此最后剩下的数字是3。

示例 1:

输入: n = 5, m = 3
输出: 3
示例 2:

输入: n = 10, m = 17
输出: 2

解题思路

((n-1)个元素情况下,剩余元素的下标 + m) % n

public int lastRemaining_1(int n, int m) {
        return f(n,m);
    }
    public int f(int n,int m){
        if (n == 1)
            return 0;
        int x = f(n - 1,m);  // 查找 有n-1个数字 的情况下,删除第m个数字 的剩余元素
        return (m + x) % n; // 根据 上一轮的计算结果,计算 本轮剩余元素
    }
 public int lastRemaining(int n,int m){
        int f = 0;
        for(int i = 2;i != n + 1;++i){
            f = (m + f) % i;
        }
        return f;
    }

题目二 (环形链表的约瑟夫问题)

在这里插入图片描述

import java.util.*;
public class Solution {
    public int ysf (int n, int m) {
        // write code here
        LinkedList<Integer> list = new LinkedList<>();
        for (int i=1;i<=n;++i){
            list.addLast(i);
        }
        int curr = 0;
        while (list.size() > 1){
            int size = list.size();
            int pos = (curr-1 + m)%size;
            list.remove(pos);
            curr = pos % (size-1);    // 若删除的是最后一个,重置curr为0
        }
        return list.get(0);
    }
}

题目变形,不求最后一个人,求剩余m-1个人的编号

第一步创建链表存1~n个数字,每次循环装数字i,指针后移,最后指向头节点形成环p.next=head
第二步while循环,数到第m个删除就行了,pre.next = p .next 再指针后移 p =pre.next

import java.util.*;
public class Solution {
    public ListNode newList(int nn) {
        ListNode  head = new ListNode(1);
        ListNode  p = head;
        for(int i = 2; i <= nn; i++) {
            ListNode node = new ListNode(i);
            p.next = node;
            p = node;
        }
        p.next = head;
        return head;
    }
    public int ysf(int n, int m) {
        ListNode head = newList(n);
        ListNode p = head;
        ListNode tmp = null;//单链表删除p,必须用辅助节点temp来存p前一个节点pre
                while(p.next != p) {
            for(int i = 1; i < m; i++) {
                tmp = p;//更新前一个节点
                p = p.next;
            }
            tmp.next = p.next;//删除p
            p = tmp.next;//指针后移
        }
        return p.val;
    }
}
posted @ 2021-03-03 22:56  your_棒棒糖  阅读(25)  评论(0)    收藏  举报