LeetCode29. 两数相除LeetCode30. 串联所有单词的子串

mac2024-04-06  48

LeetCode29. 两数相除

给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。

返回被除数 dividend 除以除数 divisor 得到的商。

示例 1: 输入: dividend = 10, divisor = 3 输出: 3

示例 2: 输入: dividend = 7, divisor = -3 输出: -2 说明:

被除数和除数均为 32 位有符号整数。除数不为 0。 假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−2^31, 2^31 − 1]。本题中,如果除法结果溢出,则返回 2^31 − 1。

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/divide-two-integers

若仅仅利用加减法和循环必然超时,这里需要利用移位思想 另外这里需要了解一下位运算符

class Solution: def divide(self, dividend: int, divisor: int) -> int: # 检查是否同正负,同0异1 sign = (dividend > 0) ^ (divisor > 0) dividend = abs(dividend) divisor = abs(divisor) count = 0 #把除数不断左移,直到它大于被除数 while dividend >= divisor: count += 1 divisor <<= 1 res = 0 while count > 0: count -= 1 divisor >>= 1 if divisor <= dividend: res += 1 << count dividend -= divisor if sign: result = -result return res if -(1<<31) <= res <= (1<<31)-1 else (1<<31)-1

LeetCode30. 串联所有单词的子串

给定一个字符串 s 和一些长度相同的单词 words。找出 s 中恰好可以由 words 中所有单词串联形成的子串的起始位置。 注意子串要与 words 中的单词完全匹配,中间不能有其他字符,但不需要考虑 words 中单词串联的顺序。

示例 1: 输入: s = “barfoothefoobarman”, words = [“foo”,“bar”] 输出:[0,9] 解释:从索引 0 和 9 开始的子串分别是 “barfoo” 和 “foobar” 。输出的顺序不重要, [9,0] 也是有效答案。

示例 2: 输入: s = “wordgoodgoodgoodbestword”, words = [“word”,“good”,“best”,“word”] 输出:[] 来源:力扣(LeetCode) 链接:: https://leetcode-cn.com/problems/substring-with-concatenation-of-all-words

遍历字符串,取等长字符串统计各个单词

class Solution: def findSubstring(self, s: str, words: List[str]) -> List[int]: from collections import Counter """ Counter()统计每个元素出现次数,返回的是字典, 键为元素,值为次数,默认按照次数由高到低排列 """ if not s or not words:return [] length = len(words[0]) all_len = len(words) * length n = len(s) # 此单词表的各单词次数统计 words = Counter(words) res = [] for i in range(n - all_len + 1): tmp = s[i:i+all_len] c_tmp = [] for j in range(0, all_len, length): #将tmp字符串截取为一个个单词填入ctmp c_tmp.append(tmp[j:j+lenth]) # 对比此时两个字符串的单词次数统计 if Counter(c_tmp) == words: res.append(i) return res
滑动窗口
class Solution: def findSubstring(self, s: str, words: List[str]) -> List[int]: from collections import Counter if not s or not words:return [] one_word = len(words[0]) word_num = len(words) n = len(s) if n < one_word:return [] words = Counter(words) res = [] # 确定开始端left for i in range(one_word): cur_cnt = 0 left = i right = i cur_Counter = Counter() while right + one_word <= n: w = s[right:right + one_word] right += one_word # 当前字符串不在words字典中,重新开始 if w not in words: left = right cur_Counter.clear() cur_cnt = 0 else: cur_Counter[w] += 1 cur_cnt += 1 # 字符串中已有单词出现频率超过字典中的则左移left while cur_Counter[w] > words[w]: left_w = s[left:left+one_word] left += one_word cur_Counter[left_w] -= 1 cur_cnt -= 1 if cur_cnt == word_num : res.append(left) return res
最新回复(0)