圆圈中最后剩下数字

24 篇文章 0 订阅

题目描述:

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

样例:

输入:n=5 , m=3
输出:3

分析:

将这n个数字存入列表中,通过举例可以得出第一次删除的数字下标为(m-1)%n记为c,
之后每一次删除的数字下标均为(c+m-1)%list.size()

public int LastRemaining_Solution(int n, int m) {
		if(n==0||m==0)
			return -1;
        List<Integer> list=new ArrayList<>();
        for(int i=0;i<n;i++)
        	list.add(i);
        int c=(m-1)%n;
        while(list.size()!=1) {
        	list.remove(c);
        	c=(c+m-1)%list.size();  
        }
        return list.get(0);
    }

环形单链表的约瑟夫问题

题目描述

一个环形单向链表的头结点head和报数的值m。
返回:最后生存下来的节点,且这个节点自己组成环形单向链表,其他节点都删掉。

题解

普通解法:

  • 1、如果链表为空或者链表节点数为1,或者m的值小于1,则不用调整就直接返回
  • 2、在环形链表中遍历每个节点,不断转圈,不断让每个节点报数。
  • 3、当报数达到m时,就删除当前报数的节点
  • 4、删除节点后,别忘了还要把剩下的节点继续连成环状,继续转圈报数,继续删除
  • 5、不停地删除,直到环形链表中只剩一个节点,过程结束。
  • 6、每删除一个节点,都需要遍历m次,一共需要删除的节点数为n-1,所以这种方法的时间复杂度为O(nm)
public static Node killNode(Node head,int m) {
		if(head==null||head.next==head||m<1) {
			return head;
		}
		Node last=head;
		//找到next节点指向头结点的节点
		while(last.next!=head) {
			last=last.next;
		}
		int count=0;
		//当next节点指向自己时结束
		while(head!=last) {
			if(++count==m) {
				last.next=head.next;
				count=0;
			}else {
				last=last.next;
			}
			head=last.next;
		}
		return head;
	}

O(N)的解法

  • 1、统计链表中节点的个数,将每个节点添加到列表中保存
  • 2、第一次删除的节点下标为(m-1)%节点个数
  • 3、下一次删除的节点下标为(上一次删除的节点的下标+m-1)%当前节点个数
  • 4、直到列表长度为1时停止
public static Node killNode1(Node head,int m) {
		if(head==null||head.next==head||m<1) {
			return head;
		}
		List<Node> list=new ArrayList();
		Node last=head;
		list.add(head);
		//找到next节点指向头结点的节点
		while(last.next!=head) {
			last=last.next;
			list.add(last);
		}
		int index=(m-1)%list.size();
		while(list.size()!=1) {
			list.remove(index);
			index=(index+m-1)%list.size();
		}
		Node n=list.get(0);
		n.next=n;
		return n;
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值