1. 数组异或操作
给你两个整数,n 和 start 。
数组 nums 定义为:nums[i] = start + 2*i(下标从 0 开始)且 n == nums.length 。
请返回 nums 中所有元素按位异或(XOR)后得到的结果。
这个题本来是很简单的,但是我做的不好,我的错误代码如下:
class Solution:
def xorOperation(self, n: int, start: int) -> int:
ans=0
nums=[]
for i in range(n):
nums[i]=start+2*i
ans=ans^nums[i]
return ans
此代码错误,原因是因为我定义了nums=[],此时如果直接写进去东西,是写不进的,所以解决办法如下
1.避免使用列表:
class Solution:
def xorOperation(self, n: int, start: int) -> int:
ans = 0
for i in range(n):
ans ^= start + 2 * i
return ans
直接异或等,就是自等,这样就避免使用列表
2.使用动态处理
class Solution:
def xorOperation(self, n: int, start: int) -> int:
ans=0
nums=[]
for i in range(n):
nums.append(start+2*i)
ans=ans^nums[i]
return ans
3.使用动态创建列表,这个其实是我最开始想到的处理,这样的处理是最直观的。
class Solution:
def xorOperation(self,n:int,start:int)->int:
ans=0
nums=[0]*n
for i in range (n):
nums[i]=start+2*i
ans=ans^nums[i]
return ans
这个题很简单,但是学习这个题目的是为了培养一个良好的编程习惯和思路,毕竟我是半路子直接开始看题的,所以规范化必须得注意,思路对了结果细节上做不到就很尴尬。
2.给定一个非负整数 num,反复将各个位上的数字相加,直到结果为一位数。返回这个结果。
示例 1:
输入: num = 38
输出: 2
解释: 各位相加的过程为:
38 --> 3 + 8 --> 11
11 --> 1 + 1 --> 2
由于 2 是一位数,所以返回 2。
这个题我也做错了,原因是去做回归调用的时候,return设置的不好,导致最后算完以后只输出了第一层的return,我的错误代码如下:
class Solution:
def addDigits(self, num: int) -> int:
num=str(num)
n=len(num)
sum=0
if n>=2:
for i in range(n):
sum=int(num[i])+sum
if sum>=10:
sol=Solution()
sol.addDigits(sum)
return sum
***重看:***想法是好的,但是实际操作的时候逻辑思考还是缺少了一点,chat教我,说在self.addDigits这里可以直接return
class Solution:
def addDigits(self, num: int) -> int:
num=str(num)
n=len(num)
sum=0
if n>=2:
for i in range(n):
sum=int(num[i])+sum
if sum>=10:
return self.addDigits(sum)
return sum
这样子修改以后就非常完美了。
3.创建一个0矩阵,不借用numpy库
transposed = [[0] * m for _ in range(n)]
这个的含义是,创建了一个n行m列的0矩阵
m, n = len(matrix), len(matrix[0])
这个是,m行n列
4.分割字符串的最大得分
给你一个由若干 0 和 1 组成的字符串 s ,请你计算并返回将该字符串分割成两个 非空 子字符串(即 左 子字符串和 右 子字符串)所能获得的最大得分。「分割字符串的得分」为 左 子字符串中 0 的数量加上 右 子字符串中 1 的数量。
示例 1:
输入:s = “011101”
输出:5
解释:
将字符串 s 划分为两个非空子字符串的可行方案有:
左子字符串 = “0” 且 右子字符串 = “11101”,得分 = 1 + 4 = 5
左子字符串 = “01” 且 右子字符串 = “1101”,得分 = 1 + 3 = 4
左子字符串 = “011” 且 右子字符串 = “101”,得分 = 1 + 2 = 3
左子字符串 = “0111” 且 右子字符串 = “01”,得分 = 1 + 1 = 2
左子字符串 = “01110” 且 右子字符串 = “1”,得分 = 2 + 1 = 3
我写的暴力解
class Solution:
def maxScore(self, s: str) -> int:
n=len(s)
ans,score=0,0
for i in range (1,n):
for j in range(0,i):
if s[j]=='0':
score+=1
for k in range(i,n):
if s[k]=='1':
score+=1
ans=max(ans,score)
score=0
return ans
简单解法:
class Solution:
def maxScore(self, s: str) -> int:
return max(s[:i].count('0') + s[i:].count('1') for i in range(1, len(s)))
没啥好说的,有时候这些奇奇怪怪的函数就是很方便,但是你就是不知道代码是等效的,可以用上面的代码解释下面的代码。这个题是一个很好的,关于指针指向数字中间分隔的例子,其中指针为(1,n)左边为(0,i)右边为(i,n)
5.统计范围内的元音字符串数
给你一个下标从 0 开始的字符串数组 words 和两个整数:left 和 right 。
如果字符串以元音字母开头并以元音字母结尾,那么该字符串就是一个 元音字符串 ,其中元音字母是 ‘a’、‘e’、‘i’、‘o’、‘u’ 。
返回 words[i] 是元音字符串的数目,其中 i 在闭区间 [left, right] 内。
示例 1:
输入:words = [“are”,“amy”,“u”], left = 0, right = 2
输出:2
解释:
- “are” 是一个元音字符串,因为它以 ‘a’ 开头并以 ‘e’ 结尾。
- “amy” 不是元音字符串,因为它没有以元音字母结尾。
- “u” 是一个元音字符串,因为它以 ‘u’ 开头并以 ‘u’ 结尾。
在上述范围中的元音字符串数目为 2 。
class Solution:
def vowelStrings(self, words: List[str], left: int, right: int) -> int:
vowel=set('aeiou')
ans=0
for i in range (left,right+1):
if words[i][0] in vowel and words[i][-1] in vowel:
ans+=1
return ans
这个代码中需要注意的是,
1.set之后,vowel是一个集合而非列表,只能在这里面查到底有没有这个东西,如果要把单词存成字符串那就要用vowels = set([‘abc’, ‘der’, ‘ios’]),这样的代码
2.right这里需要加一,因为会漏,right得取到,
3.word[i][-1]指的是倒数第一个,所以这个表达很好。
6.山脉数组的峰顶索引
给定一个长度为 n 的整数 山脉 数组 arr ,其中的值递增到一个 峰值元素 然后递减。
返回峰值元素的下标。
你必须设计并实现时间复杂度为 O(log(n)) 的解决方案。
示例 1:
输入:arr = [0,1,0]
输出:1
示例 2:
输入:arr = [0,2,1,0]
输出:1
所以二分法的逻辑就是,缩小范围,我将从代码最上面从下面一步一步分析
1.left,right这里,他们的起步都是不从0和n-1开始,我最开始在想,0和n-1怎么覆盖到呢, 其实是后续while循环的时候,最后一次循环能让指针指回来
2.while left<=right是循环条件,也就是说当left>right 的时候循环就最后一次了
3.mid=(left+right)//2这里的地板除其实很有意思,我不在乎小数点那里,不管。
4.if arr[mid] > arr[mid + 1]:左大就先赋值,然后右边范围为mid-1
为什么在 if 里要赋值 ans,而在 else 里不需要?
if 块:当 arr[mid] > arr[mid + 1] 时,mid 有可能是峰值,因此将 ans 更新为当前的 mid,以备后续使用。即使后续发现真正的峰值在 mid 的左边,ans 也可以保留这个可能的峰值位置。
else 块:当 arr[mid] <= arr[mid + 1] 时,mid 一定不是峰值,峰值必然在 mid 的右边。因此,不需要更新 ans,继续搜索右边部分即可。
5.else就只左边范围为mid+1
6.最后return ans
7.给定两个字符串 s 和 t ,它们只包含小写字母。
字符串 t 由字符串 s 随机重排,然后在随机位置添加一个字母。
请找出在 t 中被添加的字母。
示例 1:
输入:s = “abcd”, t = “abcde”
输出:“e”
解释:‘e’ 是那个被添加的字母。
示例 2:
输入:s = “”, t = “y”
输出:“y”
这个题还是我第一次过了初试然后没过总的测试的代码,很烦,原因在于,我以为题目是出现了一个额外的字母,未出现的字母,他其实是说,s=aabb,t=aabbb的话,就输出b,所以他的测试代码里没有这个可能性,我就没懂他啥意思,也就是说以后出现这种情况,要考虑有没有可能是因为思路出问题了,测试用例和题目描述是被包含关系。
***新知识:***Counter是 collections 模块中的一个类,专门用于统计可哈希对象(例如字符串中的字符)的出现次数。它返回一个字典,键是对象,值是它们的计数
from collections import Counter
s = "abcd"
t = "abcde"
print(Counter(s)) # 输出: Counter({'a': 1, 'b': 1, 'c': 1, 'd': 1})
print(Counter(t)) # 输出: Counter({'a': 1, 'b': 1, 'c': 1, 'd': 1, 'e': 1})
那么这个题就有:
diff = Counter(t) - Counter(s)
print(diff) # 输出: Counter({'e': 1})
diff_list = list(Counter(t) - Counter(s)) # 强制转为列表
print(diff_list) # 输出: ['e']
return list(Counter(t) - Counter(s))[0] # 列表第一个字母,键