解法一分析:
循环的开始和结束:循环的结束取决于圈内是否还有“人”,可以用一个变量alive表示初始人数,每一次出圈,alive - 1。判断alive是否非0即可。
如果这个人在圈内,number + 1;
如果这个人不在圈内,number + 0。
那么,在报数的时候,不需要考虑这个人在不在圈内(每一个人都需要加1或加0,所以,可以在这块优化一下程序)。

def joseph(count, doom):
	alive = count		#幸存人数 
	number = 0			#计数,当number==doom时,淘汰这个人 
	index = 0			#下标,为总人数-1 
	circle = [0 for i in range(count)]
	#0表示在这个人在约瑟夫环内,1表示这个人出圈,即“淘汰” 
	
	#只要幸存人数大于0,则一直进行循环 
	while alive > 0:
		number += 1 - circle[index];	#每轮到一个人报数,不管是"0"还是"1"都进行计数 
		if number == doom):		
		#当number==doom时,就要淘汰当前这个人
		#淘汰一个人需要做四步操作:
		#1、输出这个人的位置 
		#2、把这个人的状态从在圈内"0"改为不在圈内"1" 
		#3、幸存人数alive-- 
		#4、 计数器number归零 
			if alive == 1:
			     print(index+1)
			circle[index] = 1
			alive -= 1
			number = 0
		#与总人数count取余,则可以使index在0~count-1之间 一直循环,达到循环数组的目的 
		index = (index +1) % count
	print("\n")

解法二程序分析:
解法二在解法一的基础上进行了优化,对出圈的人的节点进行删除,可以减少时间复杂度。

假设,要删除的节点下标为curIndex,其前驱节点下标为preIndex;
circle[preIndex] = circle[curIndex];
在出圈的时候,curIndex 和preIndex 的变化有别于上面的操作:
出圈时,curIndex 需要后移,preIndex 应该不动!
每次循环,直接报数,因为被删除的人(例如上面的第四个人)不可能进行报数了。

def joseph(count, doom):
	alive = count				# 幸存人数
	number = 0				    # 报数的数
	curIndex = 0			    # 当前人下标
	preIndex = count - 1        # 前一个人下标
	
	circle = [(i+ 1) % count for i in range(count)]
	while alive > 0:
		number += 1
		if number == doom:
			if alive == 1:
			     print(curIndex+1)
			alive -= 1
			number = 0
			circle[preIndex] = circle[curIndex] #出圈操作 
		else:
			preIndex = curIndex	   #处理下一个人 
		curIndex = circle[curIndex];

解法三程序分析:
解法三里没有进行number报数,而是直接计算出需要移动的人数,然后定位到要出圈的人。

def joseph(count, doom):
	alive = count				# 幸存人数
	number = 0				    # 报数的数
	curIndex = 0			    # 当前人下标
	preIndex = count - 1        # 前一个人下标
	
	circle = [(i+ 1) % count for i in range(count)]
	
	while alive > 0:	#只要还有幸存者,就继续“杀”
		num = doom % alive - 1; #直接计算出需要移动的人数,
		#直接定位到要出圈的人
		if num == -1:
			num = alive -1
		for i in range(num):
			preIndex = curIndex
			curIndex = circle[curIndex]
		# 该人出圈!
		if alive == 1:
		    printf(curIndex+1)  
		alive -= 1
		circle[preIndex] = circle[curIndex] #真正的出圈操作!
		curIndex = circle[curIndex] #继续处理下一个人
	# 这个算法比normalJoseph.c效率提高30%!

————————————————
版权声明:本文为CSDN博主「西邮陈冠希」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_38214171/article/details/80352921
——
——————————————
版权声明:本文为CSDN博主「西邮陈冠希」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_38214171/article/details/80352921

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐