链表问题(4)----环形链

1、题目:环形单链表的约瑟夫问题

普通思路:时间复杂度O(n × m)

代码:

class Node:
    def __init__(self,value):
        self.value = value
        self.next = None
def test(head,m):
    if not head or head.next == head or m < 2:
        return head
    # last = head
    # while last.next != head:
    #     last = last.next
    count = 2
    node = head
    while node.next != node:
        if count == m:
            # last = node.next
            node.next = node.next.next
            count = 1
        node = node.next
        count += 1
    head.next = None
    # head = node
    return node
head = Node(1)
head.next = Node(2)
head.next.next = Node(3)
head.next.next.next = Node(4)
head.next.next.next.next = Node(5)
head.next.next.next.next.next = Node(6)
head.next.next.next.next.next.next = Node(7)
head.next.next.next.next.next.next.next = head
m = 3
test(head,m)

题目思路:时间O(n):

  每隔m个删除,超过n的大小,则取余来删除。

def delNum(arr,m):
    if len(arr) < 1 or m < 1:
        return
    if len(arr) == 1:
        return arr[0]
    count = 0
    while len(arr) != 1:
        count += m
        if count >= len(arr):
            count %= len(arr)
        print('删除:',arr[count])
        arr.pop(count)
    print(arr[0])
arr = [0,1,2,3,4,5,6,7,8,9]
m = 3
delNum(arr,m-1)

 

递归思路:

从1人环的0计算到10人环,结果为4。转化公式:

 

由图知,10人环中最后入海的是4号,现由其在1人环中的对应编号0来求解。

公式:其中,m为报数值,i为第几轮。

 代码1:从n个数中求出最后只留下的值

    def LastRemaining_Solution(self, n, m):
        # write code here
        if n <= 1 or m <= 0:
            return -1
        last = 0
        for i in range(2,n+1):
            last = (last + m) % i
        return last

 代码2:忽略这个代码

class Node:
    def __init__(self,value):
        self.value = value
        self.next = None
def josephus(head,m):
    last = head
    n = 1
    while last.next != head:
        last = last.next
        n += 1
    fn = 0
    for i in range(2,n+1):
        fn = (fn + m) % i
    last = head
    if fn > 1:
        for i in range(fn-1):
            last = last.next
    pre = last.next 
    last.next = None
    pre.next = pre
    return pre
head = Node(1)
head.next = Node(2)
head.next.next = Node(3)
head.next.next.next = Node(4)
head.next.next.next.next = Node(5)
head.next.next.next.next.next = Node(6)
head.next.next.next.next.next.next = Node(7)
head.next.next.next.next.next.next.next = head
m = 3
josephus(head,m)

 

题目二:

  题目思路:时间O(n):

    每隔m个删除,超过n的大小,则取余来删除。

  代码:

def delNum(arr):
    if len(arr) < 1:
        return 
    if len(arr) == 1:
        return arr[0]
    count = 0
    i = 1
    while len(arr) != 1:
        count += i
        if count >= len(arr):
            count %= len(arr)
        print('删除:',arr[count])
        arr.pop(count)
        i += 1
    print(arr[count])
arr = [0,1,2,3,4,5,6,7,8,9]
delNum(arr)
        
            
    

 

 

 

posted on 2018-10-02 17:21  吱吱了了  阅读(350)  评论(0编辑  收藏  举报

导航