python做题日记(13)

第二十九题

第二十九题题目的意思是给定被除数和除数,在不使用乘除法和取余运算的情况下,算出最终结果,结果是向零取整的整数。最简单的想法是采用不断的在被除数中减去除数,直至不能减了为止,就可以得到最终的结果。也可以利用移位运算,在之前这种想法的基础上加速减法的速度,通过移位操作就相当于每一次减去2的幂次个除数,再将这个数加到最后的结果当中。

  1. 处理符号:先确定结果正负。
  2. 取绝对值:将被除数和除数都转为正数(用 long 防止溢出)。
  3. 用位运算加速减法:每次尝试用除数的 2^n 倍去减被除数,能减多少次就加上多少倍。
  4. 处理溢出:结果超出 32 位范围时返回边界值。
python 复制代码
class Solution:
    def divide(self, dividend: int, divisor: int) -> int:
        INT_MAX = 2**31 - 1
        INT_MIN = -2**31

        # 特殊情况
        if dividend == INT_MIN and divisor == -1:
            return INT_MAX

        # 处理符号
        negative = (dividend < 0) != (divisor < 0)
        a, b = abs(dividend), abs(divisor)
        result = 0

        # 位运算加速减法
        for i in range(31, -1, -1):
            if (a >> i) >= b:
                result += 1 << i
                a -= b << i

        return -result if negative else result

第三十题

第三十题的意思是给定一个字符串,再给定一个字符串组,字符串组中每个单词的长度都一致,需要查找在给定字符串中是否存在有将字符串组中的单词按照任意顺序链接成的字符串,如果存在,则返回其起始下标。对于这个题首先需要确定在给定字符串中的匹配区间,再在这个匹配区间内检查是否符合要求,如果不符合要求需要对区间进行移动,以找到最终符合的匹配区间,并返回区间的左边界下标。

  1. 统计每个单词出现次数 ,用哈希表 word_count 记录。
  2. 确定窗口长度 :每个单词长度为 word_len,窗口总长度为 word_len * len(words)
  3. 遍历所有可能的起点 (因为单词可能不是从0开始对齐,所以要分word_len种情况)。
  4. 滑动窗口 :每次取窗口内的所有单词,统计出现次数,和 word_count 对比。
  5. 如果匹配,记录起始索引
python 复制代码
class Solution:
    def findSubstring(self, s: str, words: list[str]) -> list[int]:
        if not s or not words:
            return []
        word_len = len(words[0])
        word_num = len(words)
        total_len = word_len * word_num
        word_count = {}
        for w in words:
            word_count[w] = word_count.get(w, 0) + 1

        res = []
        for i in range(word_len):
            left = i
            count = 0
            cur_count = {}
            for j in range(i, len(s) - word_len + 1, word_len):
                word = s[j:j+word_len]
                if word in word_count:
                    cur_count[word] = cur_count.get(word, 0) + 1
                    count += 1
                    while cur_count[word] > word_count[word]:
                        cur_count[s[left:left+word_len]] -= 1
                        left += word_len
                        count -= 1
                    if count == word_num:
                        res.append(left)
                else:
                    cur_count.clear()
                    count = 0
                    left = j + word_len
        return res
  • 外层循环枚举所有对齐方式,内层滑动窗口按单词长度步进。
  • 用哈希表统计窗口内单词出现次数,遇到多余或非法单词就收缩窗口或重置。
  • 每次窗口内正好包含所有目标单词时,记录起点。