求更优/精简的同数位紧邻后继数算法(不使用itertools)
优化后的同数位紧邻后继数实现
你的原代码思路完全正确,已经抓住了找下一个排列的核心逻辑!不过我们可以从效率提升和代码精简两个方向做优化,同时让代码可读性更强:
优化点说明
- 利用降序特性替代排序:原代码中交换后对右边部分用
sorted()排序,但实际上,我们找到的右边部分原本是严格降序的(因为我们是从右往左找到第一个“左小右大”的位置),所以交换后只需要反转右边部分就能得到升序,时间复杂度从O(k log k)降到O(k)(k为右边部分长度),效率更高。 - 用
next()简化循环:把找基准点和交换点的循环换成next()生成器表达式,让代码更紧凑,同时逻辑更清晰。 - 变量名更语义化:比如用
digits代替ns,pivot代替i,让代码一眼就能看懂每个变量的作用。
优化后的代码
def find_next(n): digits = list(map(int, str(n))) length = len(digits) # 从右往左找第一个左边数字小于右边数字的位置(pivot是右边部分的起始索引) pivot = next((i for i in reversed(range(1, length)) if digits[i] > digits[i-1]), -1) if pivot == -1: return n # 没有更大的排列,返回原数 # 在右边降序序列中,找第一个比基准数字大的元素(就是最小的那个更大元素) swap_idx = next((j for j in reversed(range(pivot, length)) if digits[j] > digits[pivot-1]), pivot) # 交换基准数字和找到的元素 digits[pivot-1], digits[swap_idx] = digits[swap_idx], digits[pivot-1] # 反转右边部分(降序变升序,比排序高效) digits[pivot:] = digits[pivot:][::-1] return int(''.join(map(str, digits))) n = int(input()) print(find_next(n))
测试验证
- 输入
123→ 输出132,符合预期 - 输入
1238→ 输出1283,符合预期 - 输入
4321→ 输出4321(没有更大的排列) - 输入
132→ 输出213(正确的下一个排列)
这个版本既保留了原代码的正确性,又在效率和可读性上做了提升,而且完全不需要用到itertools库~
内容的提问来源于stack exchange,提问作者theCoder
相关产品推荐
相关产品推荐

