這是經典的約瑟夫環,並且期望剩餘的人數是2,我們這裡也做了乙個通配,可以輸入期望剩餘的人數,比如期望剩餘1個,那麼31這個位子可以存活。當然解決關鍵就是得用到單向迴圈鍊錶,語言自然選擇的是golang,當然這算是第一版本以實現功能為主,還有很多待改進的地方。
let』s go
第一.我們先演繹一下,我們從1開始報數,到三的時候自殺,然後以此類推6、9、12…可以看得出來第一圈是以3的倍數自殺,最後到39跑完一圈。
第二.我們再跑一圈,第一圈的最後乙個是39,那麼+3以後這次應該是1自殺,以此類推+3的偏移量,如果中間遇到已經死亡的,我們不計數。
這樣第二圈跑完下來最後乙個自殺的應該是41。我們就按照以上思路進行編寫,其實程式也就是我們的思考過程,只不過我們只是做了前期歸納演算,最後的規律以及實現方式還得用計算機來實現這就是計算機存在的意義。
第三.我們可以從上面的圖里看出,這是乙個環狀的結構,那麼我們要實現這樣的結構,就可以用一種資料結構來表示——單向迴圈鍊錶。我們用一張圖來解釋這個鍊錶:
從圖中可以看到,鍊錶的尾部元素的next是永遠指向head的,這樣就形成了乙個環。
好了,廢話不多說了,上**。
1.定義結構體,這裡index表示表示元素的下標,killed表示是否已經被殺,false表示存活。
type node struct
type linkedlist struct
2.插入元素,這裡只討論尾部插入,其餘的不做研究。當head為nil的時候,插入第乙個元素就是head,同時head的next指向的是head。其餘新增的元素的next一定得指向head,形成閉環。
func
(list *linkedlist)
insert
(index int
) list.len++
if list.head ==
nil curr := list.head
for curr.next != list.head
curr.next = node
node.next = list.head
}
3.實現報數自殺。這裡可輸入期望存活的人數,返回的是乙個陣列,陣列裡存的是下標。offset作為偏移,計數到3就自殺乙個,同時重置offset,這裡值得注意的是尋找下乙個存活的人,每次尋找都會做乙個迴圈查詢,直到找到還沒自殺的人為止。
func
(list *linkedlist)
selfkilled
(alivenums int)[
]int
offset++
curr = curr.next
for curr.killed
} alivearr :=
make([
]int,0
) h := list.head
for h.next != list.head
}return alivearr
}
4.遍歷插入元素,實現41個人排隊手拉手。
func
josephusproblem
(alivenums int)[
]int
for i :=
1; i <
42; i++
return list.
selfkilled
(alivenums)
}
5.最後必不可少的main函式入口。
func
main()
6.我們期望的值是16和31,這裡不做test**驅動測試了,就用簡單的main輸出。
real alive indexs:[16
31]
7.收工,整體下來主要邏輯在於selfkilled方法,這裡迴圈遍歷有點囉嗦,還有待改進,留著以後再做調整吧。
最後是完整**:
package main
import
("fmt"
)func
main()
type node struct
type linkedlist struct
func
(list *linkedlist)
insert
(index int
) list.len++
if list.head ==
nil curr := list.head
for curr.next != list.head
curr.next = node
node.next = list.head
}func
josephusproblem
(alivenums int)[
]int
for i :=
1; i <
42; i++
return list.
selfkilled
(alivenums)
}func
(list *linkedlist)
selfkilled
(alivenums int)[
]int
offset++
curr = curr.next
for curr.killed
} alivearr :=
make([
]int,0
) h := list.head
for h.next != list.head
}return alivearr
}
單向環形鍊錶解決約瑟夫問題
package com.xkp.data.linkerlist author xkp version 1.0 classname josepfu description 單向環形煉表處理約瑟夫問題 date 2020 11 30 0030 23 12 public class josepfu cla...
用單向迴圈鍊錶解決約瑟夫環問題
設有n個人圍坐一圈,現以某個人開始報數,數到m的人出列,接著從出列的下乙個人開始重新報數,數到m的人又出列,如此下去,直到所有人都出列為止.按出列順序輸出.這段 是從網上找來的,在此特別說明!include stdlib.h struct ele main u link h 末表元後繼首表元,形成環...
5 使用迴圈單向列表解決約瑟夫問題
建立乙個節點類 建立乙個環形的單向鍊錶 class circlesinglelinkedlist boynode curboy null 輔助節點,幫助構建環形鍊錶 使用for迴圈來建立環形單向鍊錶 for int i 1 i nums i else 遍歷當前環形鍊錶 public void sho...