Given a circular single linked list.Write a program that deletes every kth node until only one node is left.
After kth node is deleted, start the procedure from (k+1)th node.
e.g.list is 1->2->3->4->5->1
k=3
1. You are at 1, delete 3.
List is: 1->2->4->5->1
2. You are at 4, delete 1
List is: 2->4->5->2
3. You are at 2,delete 5
List is: 2->4->2
4. You are at 2, delete 2
List is: 4
Return 4. How efficient you can do it?

 Solution 1: Math

Let  f(n,k) denote the position of the survivor. After the  kth person is killed, we're left with a circle of  n-1, and we start the next count with the person whose number in the original problem was (k mod n)+1. The position of the survivor in the remaining circle would be f(n-1,k), if we start counting at 1; shifting this to account for the fact that we're starting at (k mod n)+1 yields the recurrence

f(n, k) = ((f(n-1, k) + k - 1) mod n) + 1, 

f(1, k) = 1

这样理解:

新数组len = n-1, 其中1th num在原数组的位置是  (k mod n)+1, 也就是 (1 + (k-1))mod n+ 1

2nd num 在原数组位置是 (2 + (k-1))mod n + 1

3rd num 在原数组位置是 (3 + (k-1))mod n + 1

After the first person (kth from begining) is killed, n-1 persons are left. So we call josephus(n – 1, k) to get the position with n-1 persons. But the position returned by josephus(n – 1, k) will consider the position starting from k%n + 1. So, we must make adjustments to the position returned by josephus(n – 1, k).

Following is simple recursive implementation of the Josephus problem. The implementation simply follows the recursive structure mentioned above.

Time Complexity, O(N), DP

 #include <stdio.h>

 int josephus(int n, int k)
{
if (n == 1)
return 1;
else
/* The position returned by josephus(n - 1, k) is adjusted because the
recursive call josephus(n - 1, k) considers the original position
k%n + 1 as position 1 */
return (josephus(n - 1, k) + k-1) % n + 1;
} // Driver Program to test above function
int main()
{
int n = 14;
int k = 2;
printf("The chosen place is %d", josephus(n, k));
return 0;
}

Solution 2: Simulate the process

Singly LinkedList

先扫一遍,确定有环,并且找到head上一跳节点,然后loop直到head.next == head

 package bloomberg;

 public class Josephus {
public class ListNode {
ListNode next;
int val;
public ListNode(int val) {
this.val = val;
this.next = null;
}
} public int survive(ListNode head, int k) {
if (head == null) return -1;
ListNode prev = head;
while (prev!=null && prev.next!=head) {
prev = prev.next;
}
if (prev == null) return -1; //not a loop
//now prev is the previous node of head
int count = 1;
while (head.next != head) {
if (count == k) {
prev.next = head.next;
head = head.next;
count = 1;
}
else {
head = head.next;
prev = prev.next;
count++;
}
}
return head.val;
} public static void main(String[] args) {
Josephus sol = new Josephus();
ListNode node1 = sol.new ListNode(1);
ListNode node2 = sol.new ListNode(2);
ListNode node3 = sol.new ListNode(3);
ListNode node4 = sol.new ListNode(4);
ListNode node5 = sol.new ListNode(5);
ListNode node6 = sol.new ListNode(6);
node1.next = node2;
node2.next = node3;
node3.next = node4;
node4.next = node5;
node5.next = node6;
node6.next = node1;
int res = sol.survive(node1, 2);
System.out.println(res);
}
}

Doubly LinkedList

可以一边loop一边确定是不是有环,while loop结束条件是 head.next != null && head.next != head, 如果出现head.next == null说明无环, 如果

head.next == head说明仅剩一个元素,正常结束

Bloomberg面经准备: Josephus problem的更多相关文章

  1. josephus Problem 中级(使用数组模拟链表,提升效率)

    问题描写叙述: 在<josephus Problem 0基础(使用数组)>中.我们提出了一种最简单直接的解决方式. 可是,细致审视代码之后.发现此种方案的效率并不高,详细体如今.当有人出局 ...

  2. 约瑟夫问题(Josephus Problem)的两种快速递归算法

    博文链接:http://haoyuanliu.github.io/2016/04/18/Josephus/ 对,我是来骗访问量的!O(∩_∩)O~~ 约瑟夫问题(Josephus Problem)也称 ...

  3. Josephus Problem的详细算法及其Python、Java实现

      笔者昨天看电视,偶尔看到一集讲述古罗马人与犹太人的战争--马萨达战争,深为震撼,有兴趣的同学可以移步:http://finance.ifeng.com/a/20170627/15491157_0. ...

  4. 算法Sedgewick第四版-第1章基础-017一约瑟夫问题(Josephus Problem)

    /************************************************************************* * * Josephus problem * * ...

  5. 约瑟夫(环)问题(Josephus problem)

    问题描述:皇帝决定找出全国中最幸运的一个人,于是从全国选拔出 n 个很幸运的人,让这 n 个人围着圆桌进餐,可是怎么选择出其中最幸运的一个人呢?皇帝决定:从其中一个人从 1 开始报数,按顺序数到第 k ...

  6. LightOJ - 1179 Josephus Problem(约瑟夫环)

    题目链接:https://vjudge.net/contest/28079#problem/G 题目大意:约瑟夫环问题,给你n和k(分别代表总人数和每次要数到k),求最后一个人的位置. 解题思路:因为 ...

  7. Java-约瑟夫问题(Josephus Problem)

    题目: 据说着名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人到,于是决定了一个自杀方 ...

  8. Josephus problem(约瑟夫问题,丢手绢问题)

    约瑟夫问题 约瑟夫环问题是一个数学应用题:已知n个人(以编号1,2,3.....,n)围坐在一张圆桌的周围.从编号为k的人开始报数,数到m的那个人出列:他的下一个人又从1开始报数,数到m的那个人又出列 ...

  9. 谁能笑到最后,约瑟夫环-Josephus问题求解

     一. 简述Josephus问题 N个人站成一环,从1号开始,用刀将环中后面一个人“消灭“”掉,之后再将刀递给下一个人,这样依次处理,最后留下一个幸存者. 二. 求解方法  1.  约瑟夫问题如果使用 ...

随机推荐

  1. poj1155 TELE (树上的背包)

    题目链接:http://poj.org/problem?id=1155 题意:给定一棵树,1为根结点表示电视台,有m个叶子节点表示客户,有n-m-1个中间节点表示中转站,每条树边有权值.现在要在电视台 ...

  2. nodejs review-01

    lesson lesson-code 05 Run your first web server 使用curl //指定方法;显示header信息 curl -X GET -i localhost:30 ...

  3. js实现复制到剪贴板功能,兼容所有浏览器

    http://www.cnblogs.com/PeunZhang/p/3324727.html https://github.com/zeroclipboard/ZeroClipboard 复制链接到 ...

  4. Educational Codeforces Round 12 E Beautiful Subarrays

    先转换成异或前缀和,变成询问两个数异或≥k的方案数. 分治然后Trie树即可. #include<cstdio> #include<algorithm> #define N 1 ...

  5. Spring Security笔记:自定义Login/Logout Filter、AuthenticationProvider、AuthenticationToken

    在前面的学习中,配置文件中的<http>...</http>都是采用的auto-config="true"这种自动配置模式,根据Spring Securit ...

  6. ZeroMQ接口函数之 :zmq_send_const – 从一个socket上发送一个固定内存数据

    ZeroMQ API 目录 :http://www.cnblogs.com/fengbohello/p/4230135.html ——————————————————————————————————— ...

  7. 普通用户ssh无密码登录设置

    这段时间在做Hadoop的环境配置,用root用户只需要按照一定的步骤进行操作就可以直接实现无密码登录,但如果使用新建用户,怎么尝试都不行. 本帖大部分都是其他人帖子的内容.如果按照下面的步骤还是不能 ...

  8. javascript面向对象(二):构造函数的继承

    本文来自阮一峰 这个系列的第一部分,主要介绍了如何"封装"数据和方法,以及如何从原型对象生成实例. 今天要介绍的是,对象之间的"继承"的五种方法. 比如,现在有 ...

  9. c++字符串

    之所以抛弃char*的字符串而选用C++标准程序库中的string类,是因为他和前者比较起来,不必 担心内存是否足够.字符串长度等等,而且作为一个类出现,他集成的操作函数足以完成我们大多数情况下(甚至 ...

  10. java面向对象_抽象类和接口

    一.抽象类 1.抽象方法:由abstract修饰.只有定义没有方法体.用一个分号结尾. 2.抽象类: 1)包含抽象方法的类必须是抽象类 2)由abstract修饰 3)不能被实例化 4)抽象类如果不被 ...