https://leetcode.cn/problems/multiply-strings
给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。
注意:不能使用任何内置的 BigInteger 库或直接将输入转换为整数。
示例 1:
输入: num1 = “2”, num2 = “3”
输出: “6”
示例 2:
输入: num1 = “123”, num2 = “456”
输出: “56088”
提示:
1 <= num1.length, num2.length <= 200
num1 和 num2 只能由数字组成。
num1 和 num2 都不包含任何前导零,除了数字0本身。
思路: 这题说num1和num2的长度可能到达200,这就是强制逐位计算的意思。假设正在计算num1的 i 位和num2的 j 位,那么乘积应该加到结果数组的 i + j 位和 i + j + 1位。(举例:123 x 456 时,3 x 6就放在结果的index=4和5的位置)。由于是从低位向高位,所以 i + j + 1位应该加上原本的数字,这个和取余就是 i + j + 1 位的结果。而这个和的进位应该加到 i + j 位。
class Solution:
def multiply(self, num1: str, num2: str) -> str:
m = len(num1)
n = len(num2)
# 总长度不会超过两个串的位数和
res = [0] * (m + n)
# 从后往前
for i in range(m-1, -1, -1):
for j in range(n-1, -1, -1):
mul = (ord(num1[i]) - ord('0')) * (ord(num2[j]) - ord('0'))
p1 = i + j
p2 = i + j + 1
s = mul + res[p2]
res[p2] = s % 10
res[p1] += s // 10
# 去除前导0
i = 0
while i < (m + n) and res[i] == 0:
i += 1
# 如果全是0,说明答案就是0
if i == (m + n):
return "0"
else:
return "".join([str(i) for i in res[i:]])
https://leetcode.cn/problems/repeated-substring-pattern/
给定一个非空的字符串 s ,检查是否可以通过由它的一个子串重复多次构成。
示例 1:
输入: s = “abab”
输出: true
解释: 可由子串 “ab” 重复两次构成。
思路: 如果存在这样的子串,那么将s拼在s的结尾处,再从index=1处查找s,找到的位置一定在第一个s的范围中。否则只能在重复的那个s里匹配到s。
class Solution:
def repeatedSubstringPattern(self, s: str) -> bool:
return (s + s).find(s, 1) != len(s)
https://leetcode.cn/problems/longest-uncommon-subsequence-i
给你两个字符串 a 和 b,请返回 这两个字符串中 最长的特殊序列 的长度。如果不存在,则返回 -1 。
「最长特殊序列」 定义如下:该序列为 某字符串独有的最长子序列(即不能是其他字符串的子序列) 。
字符串 s 的子序列是在从 s 中删除任意数量的字符后可以获得的字符串。
例如,“abc” 是 “aebdc” 的子序列,因为删除 “aebdc” 中斜体加粗的字符可以得到 “abc” 。 “aebdc” 的子序列还包括 “aebdc” 、 “aeb” 和 “” (空字符串)。
示例 1:
输入: a = “aba”, b = “cdc”
输出: 3
解释: 最长特殊序列可为 “aba” (或 “cdc”),两者均为自身的子序列且不是对方的子序列。
class Solution:
def findLUSlength(self, a: str, b: str) -> int:
if a == b: return -1
else: return max(len(a), len(b))
https://leetcode.cn/problems/longest-palindrome/
给定一个包含大写字母和小写字母的字符串 s ,返回 通过这些字母构造成的 最长的回文串 。
在构造过程中,请注意 区分大小写 。比如 “Aa” 不能当做一个回文字符串。
示例 1:
输入:s = “abccccdd”
输出:7
解释:
我们可以构造的最长的回文串是"dccaccd", 它的长度是 7。
思路: 这题可以打乱顺序,所以构建回文串的时候只需要遵循以下原则:如果一个字符出现过基数次,那可以多选一个加入结果串,但如果当前结果串已经是奇数长度,说明已经加入过单个字符了,就不再加了;所有情况下,结果串都可以加入<某字符出现次数的最大偶数个字符。
class Solution:
def longestPalindrome(self, s: str) -> int:
# 用数组记录每个字符出现的次数。没必要字典了
arr = [0] * 52
for i in s:
if ord(i) < ord('a'):
arr[26 + ord(i) - ord('A')] += 1
else:
arr[ord(i) - ord('a')] += 1
ans = 0
for i in range(52):
ans += arr[i] // 2 * 2
# 取一个奇数次的字母做中心。如果没有就不用
if arr[i] % 2 != 0 and ans % 2 == 0:
ans += 1
return ans
https://leetcode.cn/problems/generate-a-string-with-characters-that-have-odd-counts/
给你一个整数 n,请你返回一个含 n 个字符的字符串,其中每种字符在该字符串中都恰好出现 奇数次 。
返回的字符串必须只含小写英文字母。如果存在多个满足题目要求的字符串,则返回其中任意一个即可。
示例 1:
输入:n = 4
输出:“pppz”
解释:“pppz” 是一个满足题目要求的字符串,因为 ‘p’ 出现 3 次,且 ‘z’ 出现 1 次。当然,还有很多其他字符串也满足题目要求,比如:“ohhh” 和 “love”。
class Solution:
def generateTheString(self, n: int) -> str:
if n % 2 == 1:
return "a" * n
else:
return "a" + "b" * (n-1)
https://leetcode.cn/problems/count-asterisks/
给你一个字符串 s ,每 两个 连续竖线 ‘|’ 为 一对 。换言之,第一个和第二个 ‘|’ 为一对,第三个和第四个 ‘|’ 为一对,以此类推。
请你返回 不在 竖线对之间,s 中 ‘*’ 的数目。注意,每个竖线 ‘|’ 都会 恰好 属于一个对。
示例 1:
输入:s = “l|eet|co|*de|"
输出:2
解释:不在竖线对之间的字符加粗加斜体后,得到字符串:"l|eet|co|*de|” 。
第一和第二条竖线 ‘|’ 之间的字符不计入答案。
同时,第三条和第四条竖线 ‘|’ 之间的字符也不计入答案。
不在竖线对之间总共有 2 个星号,所以我们返回 2 。
class Solution:
def countAsterisks(self, s: str) -> int:
valid = True
ans = 0
for c in s:
if c == '|':
valid = not valid
elif c == '*' and valid:
ans += 1
return ans