You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

支持任意方向计数的通用约瑟夫问题Python算法优化问询

通用正负向约瑟夫问题算法优化方案

问题核心原因

原有代码的add函数修正逻辑仅在初始数组长度下符合计数预期,数组弹出元素长度缩短后,正负移位的索引起点更新规则没有统一对齐,导致后续索引计算出现偏移。

优化思路

Python 内置的取模运算符%天然支持负数运算,返回结果永远和除数(数组长度)同号,也就是结果必然落在0 ~ len(arr)-1的合法索引范围内,无需额外分支判断修正负数索引。

优化后代码(最简无额外分支版本)

如果你定义shift为从当前起始位置的下一个元素开始移动的步数(正数向右,负数向左,移动后到达的位置即为淘汰位置),可以完全删除冗余的add函数,代码如下:

def josephus(arr, start, shift):
    if len(arr) == 1:
        return arr
    # 单行统一计算淘汰索引,正负移位通用,无额外判断
    pop_idx = (start + shift) % len(arr)
    arr.pop(pop_idx)
    print(arr)
    # 下一轮起始位置即为当前淘汰位置(pop后后续元素前移,该位置就是下一轮计数起点)
    return josephus(arr, pop_idx, shift)

size = int(input())
people = list(range(1, size + 1))
start = int(input()) - 1
shift = int(input())
print(people)
josephus(people, start, shift)

适配计数个数场景的版本

如果你需要保持shift的定义为计数的总个数(从当前起始位置作为第1个开始数,数到第abs(shift)个淘汰,正负代表方向),仅需要把索引计算逻辑调整为如下,仅保留1次符号判断,无其他额外分支:

def josephus(arr, start, shift):
    if len(arr) == 1:
        return arr
    sign = 1 if shift >=0 else -1
    pop_idx = (start + shift - sign) % len(arr)
    arr.pop(pop_idx)
    print(arr)
    return josephus(arr, pop_idx, shift)

size = int(input())
people = list(range(1, size + 1))
start = int(input()) - 1
shift = int(input())
print(people)
josephus(people, start, shift)

验证说明

两种版本均支持任意正负shift取值,无需额外边界判断,运行逻辑完全统一,不会出现后续索引计算错误的问题。

内容的提问来源于stack exchange,提问作者lesobrod

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 20:09:03