剑指offer_圆圈中最后剩下的数字

/*
圆圈中最后剩下的数字

思路:
循环队列,但队列是线性表,删除需要移动元素
对于删除操作多的需求,考虑循环链表

*/
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));
	}
}

点赞