/*
圆圈中最后剩下的数字
思路:
循环队列,但队列是线性表,删除需要移动元素
对于删除操作多的需求,考虑循环链表
*/
class ListNode
{
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
class LastRemaining
{
//O(mn)
public static int lastRemaining(int n, int m) {
if (n<1||m<1)
{
return -1;
}
//创建循环链表将0~n-1放进去
ListNode head=new ListNode(0);
ListNode temp=head;
for (int i=1; i<n;i++ )
{
ListNode ln=new ListNode(i);
temp.next=ln;
temp=temp.next;
}
temp.next=head;
//从前到后依次删除第m个
temp=head;
while (temp.next!=temp)//只剩一个元素时终止
{
int count=1;
while (count<m-1)//temp走到待删除结点的前一个
{
temp=temp.next;
count++;
}
temp.next=temp.next.next;
temp=temp.next;
}
return temp.val;
}
//剑指offer,利用映射推倒递推公式,O(n)
public static int lastRemaining2(int n, int m)
{
if (n<1||m<1)
{
return -1;
}
if (n==1)
{
return 0;
}
return (lastRema54ining2(n-1,m)+m)%n;
}
public static void main(String[] args)
{
System.out.println(lastRemaining2(5,3));
}
}