AI 刷题 31. 不同整数的计数问题 题解 | 豆包MarsCode AI刷题

100 阅读4分钟

39. 计算位置 x 到 y 的最少步数

问题描述

小R有一个字符串 word,该字符串由数字和小写英文字母组成。小R想用空格替换每一个不是数字的字符。然后,他希望统计在替换后剩下的整数中,不同整数的数目。

思路解析

  • 整体思路方向
    首先要对给定的字符串 word 进行遍历,根据字符的类型(数字或非数字)来进行相应处理,将非数字字符替换成空格,得到一个新的字符串,这个新字符串里的数字是按要求分隔开的。接着从这个新字符串中提取出所有数字,再利用集合的去重特性来统计不同数字的数量,以此实现最终目标。

  • 各环节思路

    • 字符判断与替换环节:需要逐个检查字符串 word 中的字符,判断其是否为数字。Python 中提供了方便的字符串方法 isdigit() 来做此判断。对于不是数字的字符,按照要求将其替换为空格,通过循环遍历整个字符串来完成对所有字符的这种处理,最终得到处理后的新字符串,这一步是对原始字符串按规则进行初步改造的关键思路。
    • 整数提取环节:经过前面替换操作后得到的新字符串中,数字之间是由空格隔开的,此时可以利用字符串的 split() 方法,依据空格这个分隔符把字符串分割开,从而得到一个包含所有数字(但此时还是字符串形式)的列表,这是将目标数字从整体字符串里分离出来的思路要点。
    • 去重统计环节:为了统计不同整数的数目,考虑到集合元素的唯一性,也就是集合中不会有重复元素这一特性,我们把从前面步骤提取出来的数字列表中的元素先转换为整数类型,再添加到集合中,集合会自动去除重复的整数,最后只需统计集合中元素的个数,就能得出不同整数的数目,这是借助集合巧妙达成最终统计目的的核心思路所在。

解题步骤

  1. 字符判断与替换步骤
  • 首先定义了一个空字符串 new_word,用于存放经过处理后的字符串结果。
  • 接着使用 for 循环遍历输入的字符串 word 中的每一个字符 char
  • 通过 char.isdigit() 判断字符 char 是否是数字,如果是数字就把该字符添加到 new_word 中,如果不是数字就添加一个空格到 new_word 中,这样就完成了按照要求对原始字符串 word 的替换操作,得到了新字符串 new_word
  1. 整数提取步骤: 这行代码利用字符串的 split() 方法,以空格作为分隔符,将上一步得到的新字符串 new_word 进行分割,返回一个列表 num_list,列表里的元素就是之前新字符串中被空格分隔开的数字(此时还是字符串形式)。
  2. 去重统计步骤
  • 首先使用了生成式 (int(num) for num in num_list),它会遍历 num_list 中的每个字符串元素,把它们逐个转换为整数类型,然后将这些整数添加到集合 unique_nums 中,由于集合的去重特性,重复的整数在集合中只会保留一个。
  • 最后通过 len(unique_nums) 来获取集合中元素的个数,这个个数就是我们最终想要统计的不同整数的数目,将其存储在变量 result 中。

复杂度分析

时间复杂度: 整体算法时间复杂度为O(n) 。遍历字符串 word(长度为 n)进行字符替换是O(n),分割新字符串及后续集合操作中,各部分操作时间复杂度与 n 相关或为常数级,主导的仍是O(n),随输入字符串变长,执行时间线性增长。

空间复杂度: 空间复杂度同样为O(n)。定义的新字符串、提取数字的列表及存储不同整数的集合,在最坏情况占用空间与 word 长度 n 相关,额外空间随输入字符串长度增加大致呈线性增长。

Code

import math;

def solution(x_position, y_position):
    dis = abs(x_position - y_position)  # 计算 x 到 y 的距离
    step_count = 0
    result = 2e9
    
    for peak in range(1, dis): # 枚举步数峰值
        # 等差数列求和:首项为 1, 末项为峰值
        # S = peak(1+peak)/2
        # 2S-peak  为走的步数, 即 peak*peak
        # peak*2-1 为走的次数
        diff = dis - peak*peak
        if(diff < 0): # 如果已经走超了,就代表不可能存在更大的峰值
            return step_count
        step_count = peak*2 - 1
        # 按峰值快步前进
        step_count += int(diff / peak) # 记得强制类型转换,下取整
        diff %= peak
        if(diff != 0):
            # 如果步数不够。则需要补充一步补齐
            step_count += 1
        result = min(step_count, result) # 更新最小步数
    return step_count

if __name__ == "__main__":
    #  You can add more test cases here
    print(solution(12, 6) == 4)
    print(solution(34, 45) == 6)
    print(solution(50, 30) == 8)