目录
一、35 搜索插入位置
- 题目描述
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
你可以假设数组中无重复元素。
示例 1:
输入: [1,3,5,6], 5
输出: 2
- 分析
直接使用二分查找 - 代码
class Solution:
def searchInsert(self, nums, target):
left = 0
right = len(nums)
while left < right:
mid = (left + right) // 2
if nums[mid] > target:
right = mid
elif nums[mid] < target:
left = mid + 1
else:
return mid
return left
二、202 快乐数
- 题目描述
编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是无限循环 但始终变不到 1。如果 可以变为 1,那么这个数就是快乐数。
如果 n 是快乐数就返回 True ;不是,则返回 False 。
示例:
输入:19
输出:true
解释:
12 + 92 = 82
82 + 22 = 68
62+ 82 = 100
12 + 02 + 02 = 1
-
分析
由于存在无限循环的情况,确定何时跳出循环是解决这个问题的关键,由于集合的key不重复存在,考虑采用判断新生成的数是否包含在已建立的集合中来判断是否重复出现,若重复出现则不是快乐数,跳出循环。 -
代码
class Solution:
def isHappy(self,n):
set_1 = set()
while True:
sum = 0
while n > 0:
tmp = n%10
sum += tmp ** 2
n = n//10
if sum in set_1:
return False
else:
set_1.add(sum)
n = sum
if n == 1:
return True
三、205 同构字符串
- 题目描述
给定两个字符串 s 和 t,判断它们是否是同构的。
如果 s 中的字符可以被替换得到 t ,那么这两个字符串是同构的。
所有出现的字符都必须用另一个字符替换,同时保留字符的顺序。两个字符不能映射到同一个字符上,但字符可以映射自己本身。
示例 1:
输入: s = “egg”, t = “add”
输出: true
示例 2:
输入: s = “foo”, t = “bar”
输出: false
- 分析
考虑使用字典表示s到t的一一映射,若s的第i个字符不在字典中,而t的第i个字符在字典中,则返回False,若都不在则创建新字典。若s的第i个字符在字典中,但映射与t的第i个字符不同,则返回False。 - 代码
class Solution:
def isIsomorphic(self, s: str, t: str):
dic = {}
for i in range(len(s)):
if s[i] not in dic:
if t[i] in dic.values():
return False
dic[s[i]] = t[i]
else:
if dic[s[i]] != t[i]:
return False
return True
四、242 有效的字母异位词
- 题目描述
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
示例 1:
输入: s = “anagram”, t = “nagaram”
输出: true
示例 2:
输入: s = “rat”, t = “car”
输出: false
- 分析
与上题相似,考虑使用字典表示每个字符对应出现的次数,若不相同则返回False。 - 代码
class Solution:
def isAnagram(self, s: str, t: str):
dic = {}
if len(s) != len(t):
return False
for i in range(len(s)):
dic[s[i]] = s.count(s[i])
for i in range(len(t)):
try:
if dic[t[i]] != t.count(t[i]):
return False
except:
return False
return True
五、290 单词规律
- 题目描述
给定一种规律 pattern 和一个字符串 str ,判断 str 是否遵循相同的规律。
这里的遵循指完全匹配,例如, pattern 里的每个字母和字符串 str 中的每个非空单词之间存在着双向连接的对应规律。
示例1:
输入: pattern = “abba”, str = “dog cat cat dog”
输出: true
示例 2:
输入:pattern = “abba”, str = “dog cat cat fish”
输出: false
- 分析
与205类似,使用字典表示一一映射。 - 代码
class Solution:
def wordPattern(self, pattern: str, str: str):
dic = {}
str_1 = str.split(' ')
if len(pattern) != len(str_1):
return False
for i in range(len(pattern)):
if pattern[i] not in dic:
if str_1[i] in dic.values():
return False
dic[pattern[i]] = str_1[i]
else:
if dic[pattern[i]] != str_1[i]:
return False
return True
六、349 两个数组的交集
- 题目描述
给定两个数组,编写一个函数来计算它们的交集。
示例 1:
输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2]
示例 2:
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[9,4]
- 分析
先将数组转化为集合,再进行集合的交集运算直接返回交集。 - 代码
class Solution:
def intersection(self, nums1, nums2):
return list(set(nums1) & set(nums2))
七、350 两个数组的交集 II
- 题目描述
给定两个数组,编写一个函数来计算它们的交集。
示例 1:
输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2,2]
示例 2:
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[4,9]
说明:
输出结果中每个元素出现的次数,应与元素在两个数组中出现次数的最小值一致。可以不考虑输出结果的顺序。
- 分析
与上题相似,先将数组转化为集合,再进行集合的交集运算,对交集中的元素个数进行判断后返回列表。 - 代码
class Solution:
def intersection(self, nums1, nums2):
s = list(set(nums1) & set(nums2))
inter = []
for item in s:
for i in range(min(nums1.count(item), nums2.count(item))):
inter.append(item)
return inter
八、410 分割数组的最大值
- 题目描述
给定一个非负整数数组和一个整数 m,你需要将这个数组分成 m 个非空的连续子数组。设计一个算法使得这 m 个子数组各自和的最大值最小。
示例:
输入:
nums = [7,2,5,10,8]
m = 2
输出:
18
解释:
一共有四种方法将nums分割为2个子数组。
其中最好的方式是将其分为[7,2,5] 和 [10,8],
因为此时这两个子数组各自的和的最大值为18,在所有情况中最小。
-
分析
以得出结论,结果必定落在【max(nums), sum(nums)】这个区间内,因为左端点对应每个单独的元素构成一个子数组,右端点对应所有元素构成一个子数组。
然后可以利用二分查找法逐步缩小区间范围,当区间长度为1时,即找到了最终答案。 -
代码
class Solution(object):
def splitArray(self, nums, m):
if len(nums) == m:
return max(nums)
left, right = max(nums), sum(nums)
while left < right:
mid = (left + right) // 2
temp, cnt = 0, 1
for num in nums:
temp += num
if temp > mid:
temp = num
cnt += 1
if cnt > m:
left = mid + 1
elif cnt <= m:
right = mid
return left
九、451 根据字符出现频率排序
- 题目描述
给定一个字符串,请将字符串里的字符按照出现的频率降序排列。
示例 :
输入:
“tree”
输出:
“eert”
解释:
'e’出现两次,'r’和’t’都只出现一次。
因此’e’必须出现在’r’和’t’之前。此外,"eetr"也是一个有效的答案。
- 分析
使用字典统计频率,对字典的value进行排序,最终根据key的字符串乘上value次数,组合在一起输出。 - 代码
class Solution:
def frequencySort(self, s: str):
c = collections.Counter(s)
tmp = [[k, v] for k, v in c.items()]
tmp.sort(key=lambda x: x[1], reverse=True)
res = ""
for i in tmp:
res += i[0] * i[1]
return res
十、540 有序数组中的单一元素
- 题目描述
给定一个只包含整数的有序数组,每个元素都会出现两次,唯有一个数只会出现一次,找出这个数。
示例:
输入: [1,1,2,3,3,4,4,8,8]
输出: 2
注意: 您的方案应该在 O(log n)时间复杂度和 O(1)空间复杂度中运行。
- 分析
判断mid两边数组的长度是奇数还是偶数,选择奇数的一方继续二分 - 代码
class Solution:
def singleNonDuplicate(self, nums):
left = 0
right = len(nums) - 1
while left < right:
mid = (left + right) // 2
if (mid == 0 or nums[mid] != nums[mid - 1]) and nums[mid] != nums[mid + 1]:
return nums[mid]
elif nums[mid] == nums[mid + 1]:
if (mid - left) % 2 == 0:
left = mid
else:
right = mid - 1
else:
if (mid - left + 1) % 2 == 0:
left = mid + 1
else:
right = mid
return nums[left]