数组至多一次数位交换转严格递增序列的Python代码调试
问题描述
- 给定数字数组,允许选择最多1个数字重排其所有数位(前导零重排后自动忽略,例如
800可重排为008对应数值8),判断能否让最终数组成为严格递增序列。 - 示例:输入
[2, 4, 800, 12],将800重排为8后得到[2,4,8,12]满足要求,返回True。
现有实现与异常表现
当前编写的代码如下:
def solution(numbers): swapped = 0 for i in range(len(numbers)-1): if numbers[i] > numbers[i+1]: if swapped >= 1: return False s1= int(''.join(sorted(str(numbers[i])))) if s1 < numbers[i+1]: if i > 0 and s1 >= numbers[i-1]: numbers[i] = s1 swapped += 1 continue s2 = int(''.join(sorted(str(numbers[i+1]), reverse=True))) if s2 >= numbers[i]: numbers[i+1] = s2 swapped += 1 continue return True
该代码在测试用例[13,31,30]上错误返回True,该用例正确结果应为False,暂未定位到问题。
问题根源
逐行跟踪代码执行[13,31,30]的流程即可定位错误:
- 遍历到
i=0时,13 < 31无逆序,直接进入下一轮循环。 - 遍历到
i=1时,31 > 30触发逆序修复逻辑,此时还未使用交换次数:- 首先计算前一个数31重排能得到的最小值
s1=13,判断13 < 30成立;随后判断前序元素关系时,代码写的是s1 >= numbers[i-1](即13 >=13),条件成立,于是将数组第1位改为13,消耗1次交换次数,继续循环。
- 首先计算前一个数31重排能得到的最小值
- 循环结束后直接返回
True,但此时数组为[13,13,30],存在相邻相等的情况,根本不满足严格递增要求。
具体有3处逻辑漏洞:
- 判断重排后的数和相邻元素的大小关系时,误用了大于等于
>=,但严格递增要求必须是严格大于>,等于的情况属于非法。 - 当尝试「重排前一个数为最小值」「重排后一个数为最大值」两种方案都不满足要求时,没有直接返回
False,会出现逆序对未被修复就继续向后遍历的问题。 - 判断重排后一个数的合法性时,同样用了
>=而非>,会引入相邻相等的非法情况。
修复后代码
def solution(numbers): swapped = 0 n = len(numbers) for i in range(n-1): if numbers[i] < numbers[i+1]: continue if swapped >= 1: return False # 尝试重排当前i位置的数为最小值 s1 = int(''.join(sorted(str(numbers[i])))) if s1 < numbers[i+1]: if i == 0 or s1 > numbers[i-1]: numbers[i] = s1 swapped += 1 continue # 尝试重排i+1位置的数为最大值 s2 = int(''.join(sorted(str(numbers[i+1]), reverse=True))) if s2 > numbers[i]: numbers[i+1] = s2 swapped += 1 continue # 两种方案都无法修复当前逆序对,直接返回False return False return True
验证测试用例[13,31,30]:i=1时s1=13不满足大于前序13的要求,s2=30不满足大于31的要求,直接返回False,结果正确。原示例用例[2,4,800,12]也可正常返回True。
内容的提问来源于stack exchange,提问作者fadshape
相关产品推荐
相关产品推荐

