力扣12:整数反转
给出一个32位的有符号整数,你需要将这个整数中每位上的数字进行反转。
示例1:
输入:123
输出:321
示例2:
输入:-123
输出:-321
示例3:
输入:120
输出:21
注意:
假设我们的环境只能存储得下32位的有符号整数,则其数值范围为 [−2^31, 2^31 − 1],请根据这个假设,如果反转后整数溢出那么返回0。
解题思路:整数转化为字符串,用索引反转字符,负数的符号拼接。由于规定了数值范围,加条件判断。
代码:
class Solution:
def reverse(self,x:int)->int:
x = str(x)
if x[0]== '-': #判断带-号的数字
x = int('-'+x[:0:-1]) #保留符号,数字反转
else:
x = int(x[::-1])
if x < -2147483648 or x >2147483648:
return 0
else:
return x # x为以上反转后的数字,而非原来的数字
力扣13:两数之和II-输入有序组
给定一个已按照升序排列的有序数组,找到两个数使得它们相加之和等于目标数。
函数应该返回这两个下标值index1和index2,其中index1必须小于index2
说明:
- 返回的下标值(index1和index2)不是从零开始的。
- 你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。
示例:
输入:numbers = [2,7,11,15],target = 9
输出:[1,2]
解释:2与7之和等于目标数9.因此index1=1,index2=2.
方法1:双指针
- left指针从左往右扫,right指针从右往左扫
- 如果numbers[left]+ numbers[right] ==target说明匹配输出left+1和right+1(下标从1开始,所以加1)
- 如果numbers[left]+numbers[right] < target说明两数之和需要增加,左边指针往右移(数组升序排列)
- 如果numbers[left]+numbers[right] > target说明两数之和需要减少 右边指针左移(数组升序排列)
代码:
class Solution(object):
def teoSum(self,numbers,target):
left = 0
right =len(numbers)-1
while left < right:
if numbers[left]+numbers[right] == target:
return [left+1,right+1]
elif numbers[left]+numbers[right] < target:
left += 1
else:
right -= 1
方法二:需要额外的空间(字典)存储已经扫过的元素的值和下标
- 每次在字典中查找有没有target-numbers[i]
- 如果有,则输出对应的i+1和字典中对应键的值
- 如果没有,将numbers[i]加入字典中
class Solution(object):
def twoSum(self,numbers,target):
dict_l = {} # 存放的k:v,数组:下标
for i in range(len(numbers)):
n = target-numbers[i]
if n in dict_l:
return [dict_l[n],i+1]
dict_l[numbers[i]] = i+1
力扣14:旋转字符串
给定两个字符串A和B.
A的旋转操作就是将A最左边的字符移动到最右边。例如,若A = 'abcde',在移动一次之后结果就是'bcdea'。如果在若干次旋转操作之后,A能变成B,那么返回True。
示例:
示例1:
输入:A = 'abcde',B = 'cdeab'
输出:true
示例2:
输入:A = 'abcde',B = 'abced'
输出:false
解题思路:字符旋转之后,长度相同,由于移动在最后面,所以,用2A字符串完美包含B
class Solution:
def rotateString(self,A:str,B:str)->bool:
return len(A) == len(B) and B in A+A
力扣15:最后一块石头的重量
有一堆石头,每块石头的重量都是正整数,每一回合,从中选出两块最重的石头,然后将它们一起粉碎。假设石头的重量分别为x和y,且x<=y。那么粉碎的可能结果如下:
- 如果
x = y
,那么两块石头都会被完全粉碎。 - 如果
x != y
,那么重量为x的石头将会完全粉碎,而重量为y的石头新重量为y-x。
最后,最多只会剩下一块石头。返回此石头的重量。如果没有石头剩下,就返回0.
解题思路:现将石头由大到小排列,如果石头的长度大于1,一直粉碎一直爽。
class Solution:
def lastStoneWeight(self,stones:List[int])->int:
stones.sort(reverse=true) #将列表从小到大排列
while(len(stones)>1):
if stones[0] == stones[1]: #x == y
stones.pop(0) #删除y
stones.pop(0) #删除x
else:
stones[0]=stones[0]-stones[1] #最大的石头重量为y-x
stones.pop(1) #删除x
stones.sort(reverse=True) #将删除之后的列表进行排序
if stones: #列表存在
return stones[0] #返回最后的石头重量
return 0 #否则返回0
力扣16:找不同
给定两个字符串s和t,他们只包含小写字母。字符串t由字符串s随机重排,然后在随机位置添加一个字母。请找出在t中被添加的字母。
示例:
s = "abcd"
t = "abcde"
输入:e
解释:
'e'是那个被添加的字母
解题思路:先将字符串转化为列表,将s中的字母取出来与t中取出来的字母进行比较,相同则删除s中字母,最后t中只剩下一个元素
class Solution:
def findTheDifference(self,s:str,t:str)->str:
list_s = list(s) # 将s字符串转化为列表
list_t = list(t) # 将t字符串转化为列表
for i in range(len(list_s)): # 循环len(list_s)
for j in range(len(list_t)):
if list_s[i] == lsit_t[j]: # 如果s列表中的字母,在t列表中
del list_t[j] #删除
break
result = ''.join(list_t)
return result
力扣17:加一
给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一。
最高为数字存放在数组的首位,数组中每个元素只存储一个数字。
你可以假设除了整数0之外,这个整数不会以零开头。
示例1:
输入:[1,2,3]
输出:[1,2,4]
解释:输入数组表示数字123。
示例2:
输入:[4,3,2,1]
输出:[4,3,2,1]
- 遍历
digits
,判断每位是否为9
,若不是则+1
并返回,否则将此位置0
; - 对于
digits
里全为9
的情况,需要扩展list,并将首位置为1
。
class Solution:
def plusOne(self,digits:[int])->[int]:
for i in range([len(digits)-1,-1,-1]): # 先判断个位的,再判断十位。
if digits[i] != 9: # 位数字是否为9
digits[i] += 1 # 不是10,位数字加1
return digits
digits[i] = 0 # 位数字全是9,置零
digits[0] = 1 # 首位置1
digits.append(0) # 末尾追加0
return digits
力扣18:字符串中的第一个唯一字符
给定一个字符串,找到它的第一个不重复的字符,并返回它的索引。如果不存在,则返回-1。
案例:
s = "leetcode"
返回0.
s = "loveleetcode"
返回2.
class Solution:
def firstUniqChar(self,s:str)->int:
for i in range(len(s)):
if s.find(s[i]) == s.rfind(s[i]) # 左边找字母的索引与右边字母索引相同
return i
return -1
find是从左往右搜索,rfind是从右往左搜索,都是返回第一个匹配的下标。如果两者一致,证明这个就是唯一值。
python 100题:一题 九九乘法表
输出9*9乘法口诀表
程序分许:分行与列考虑,共9行9列,i控制行,j控制列。
for i in range(1,10): # 循环9次,
for j in range(1,i+1): #对应1,到i+1
print(f'{i}*{j}={i*j}'',end=' ')
print() #控制换行
列表转字典
列表转换为字典
i = ['a','b']
l = [1,2]
print(dict(zip(i,l))) #zip()函数,第一个值转化为keys值,第二个为values
{'a': 1, 'b': 2}
数字组合
有四个数字:1,2,3,4能组成多少个互不相同且无重复数字的三位数?各是多少?
程序分析:遍历全部可能,把有重复的去掉。
total = 0
for i in range(1,5):
for j in range(1,5):
for k in range(1,5):
if ((i!=j)and(j!=k)and(k!=i)): #重复的全部去掉
print(i,j,k)
total += 1
print(total)
1 2 3
1 2 4
1 3 2
1 3 4
1 4 2
1 4 3
2 1 3
2 1 4
2 3 1
2 3 4
2 4 1
2 4 3
3 1 2
3 1 4
3 2 1
3 2 4
3 4 1
3 4 2
4 1 2
4 1 3
4 2 1
4 2 3
4 3 1
4 3 2
24
简便方法:用itertools中的permutations即可。
import itertools
sum2 = 0
a = [1,2,3,4]
for i in itertools.permutations(a,3):
print(i)
sum2 += 1
print(sum2)
itertools库 combinations()和permutations 组合和排列选项的方法
import itertools
s = [1,2,3]
#组合
#组合
print(list(itertools.combinations('abc',2)))
#排列
print(list(itertools.permutations(s,3)))
[('a', 'b'), ('a', 'c'), ('b', 'c')]
[(1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1)]
实例009:暂停一秒输出
程序分析:暂停一秒输出
import time
for i in range(4):
print(str(int(time.time()))[-2:]) #time.time(),从1970开始的秒数
time.sleep(1) #睡眠一秒
实例045:求和
题目:统计1到100之和
res = 0
for i in range(1,101):
res += i
print(res)
交换位置
输入数组,最大的与第一个元素交换,最小的与最后一个元素交换,输出数组。
li = [3,2,5,7,8,1,5]
li[-1],li[li.index(min(li))] = li[li.index(min(li))],li[-1]
m = li[0]
ind = li[ind]
li[ind] = m
print(li)
center()居中对齐
描述:返回一个长度为width,两边用fillchar(单字符)填充的字符串,即字符串str居中,两边用fillchar填。若字符串的长度大于width,则直接返回字符串str
语法:str.center(width,"fillchar")->str返回字符串 注意:引号不可省略
print('i love python'.center(40,"*"))
*************i love python**************
print('i love python'.center(1,"*"))
i love python
print('i love python'.center(39,"#"))
#############i love python#############
ljust()、rjust()左对齐,右对齐
print('i love python'.ljust(40,'*'))
i love python***************************
print('i love python'.rjust(40,'*'))
***************************i love python
力扣728:自除数
自除数是指可以被它包含的每一位数除尽的数。
例如:128是一个自除数,因为128 % 1 == 0
,128 % 2 ==0
,128 % 8 ==0
。
还有,自除数不允许包含0。
给定上边界数字,输出一个列表,列表的元素是边界(含边界)内所有的自除数。
示例1:
输入:
上边界left = 1,下边界right = 22
输出:[1,2,3,4,5,6,7,8,9,11,12,15,22]
注意:每一个输入的参数的边界满足1<= left <=right<=10000。
解题思路:将上边界和下边界之间的数字循环取出,每个数字转化为字符串循环取出字符,然后如果字符包含0以及余数不为0的,则不会添加到列表中。
class Solution:
def selfBividingNumbers(self,left:int,right:int)->List[int]:
res = []
for i in range(left,right+1):
for j in str(i):
if j == '0' or i %int(j) !=0:
break # 中断一个数的取字符循环
else: #for循环有break,则不会添加到列表中
res.append(i)
return res
力扣:Nim游戏
你和你的朋友,两个人一起玩Nim游戏:桌子上有一推石头,每次你们轮流拿掉1-3块
石头。拿掉最后一块石头的人就是获胜者。你作为先手。
你们是都是聪明人,每一步都是最优解。编写一个函数,来判断你是否可以在给定石头数量的情况下赢得游戏。
示例:
输入:4
输出:false
解释:如果堆中有4块石头,那么你永远不会赢得比赛;因为无论你拿走1块、2块、还是3块石头,最后一块石头总是会被你的朋友拿走。
分析:当n = 1,2,3时,你赢得游戏
当n = 4时,无论你取多少个,你不会赢得比赛
n = 5时,你取1个,你赢了,剩下4个
n = 6时,你取2个,你赢了,剩下4个
n = 7时,你取3个,你赢了,剩下4个
n = 8时,你取多少个,你不会赢,
n = 9时,你取1个,你赢了,剩下8个,
经分析发现,当n % 4 == 0时,无论我取多少个,我都不会赢
class Solution:
def canWinNim(self,n:int)->bool:
return bool(n % 4) # 0,None,{},[],false的布尔值为false,其他为true
力扣852:山脉数组的峰顶索引
我们把符合下列属性的数组A
称为山脉:
A.length >=3
- 存在
0 < i <A.length-1
,使得A[0] < A[1] < ... A[i-1] < A[i] > A[i+1] > ... > A[A.length - 1]
给定一个确定为山脉的数组,返回任何满足``A[0] < A[1] < ... A[i-1] < A[i] > A[i+1] > ... > A[A.length - 1]的
i` 的值。
示例1:
输入:[0,1,0]
输出:1
示例2:
输入:[0,2,1,0]
输出:1
代码:
class Solution:
def peakIndexInMountainArray(self,A:List[int])->int:
for i in range(1,len(A)-1):
if A[i] > A[i-1] and A[I] > A[i+1]:
return i
解题思路:根据示例,可以看出山脉的特征是中间高,两边低。同时不取第一个和最后一个数。满足山脉条件就可以输出i。
力扣1025:除数博弈
爱丽丝和鲍勃一起玩游戏,他们轮流行动。爱丽丝先手开局。
最初,黑板上有一个数字 N 。在每个玩家的回合,玩家需要执行以下操作:
选出任一 x,满足 0 < x < N 且 N % x == 0 。
用 N - x 替换黑板上的数字 N 。
如果玩家无法执行这些操作,就会输掉游戏。
只有在爱丽丝在游戏中取得胜利时才返回 True,否则返回 false。假设两个玩家都以最佳状态参与游戏。
示例1:
输入:2
输出:true
解释:爱丽丝选择1,鲍勃无法进行操作。
示例2:
输入:3
输出:false
解释:爱丽丝选择1,鲍勃也选择1,然后爱丽丝无法进行操作。
class Solution:
def divisorGame(self,N:int)->bool:
return N % 2 == 0
分析:当N为偶数时,爱丽丝胜利。
力扣:增减字符串匹配
给定只含"I"
(增大)或"D"
(减小)的字符串"D"
(减小)的字符串S
,令N=S.length
。
返回[0,1,...,N]
的任意排列A
使得对于所有i=0,...,N-1
,都有“
- 如果
S[i] == "I",那么A[i] < A[i+1]
- 如果
S[i] == "D"
,那么A[i] > A[i+1]
示例1:
输出:"IDID"
输出:[0,4,1,3,2]
示例2:
输出:"III"
输出:[0,1,2,3]
class Solution:
def diStringMatch(self,S:str)->List[int]:
left = 0
right = len(S) # 长度
A = []
for i in S:
if i =='I': # 'I'从小到大添加
A.append(left)
left += 1
else: # 'D'从大到小添加
A.append(right)
right -= 1
A.append(right) # 不在S中的,从小到大添加
return A
力扣191:位的个数
编写一个函数,输入是一个无符号整数,返回其二进制表达式中数字位数'1'的个数(也被称为汉明重量)。
示例1:
输入:00000000000000000000000000001011
输出:3
解释:输入的二进制串 00000000000000000000000000001011 中,共有三位为 '1'
示例2:
输入:00000000000000000000000010000000
输出:1
解释:输入的二进制串00000000000000000000000010000000 中,共有一位为'1'。
解法一:
class Solution(object):
def hammingWeight(self,n):
return str(bin(n).count('1'))
解法二:
手动循环计数1的个数。
class Solution(object):
def hammingWeight(self,n):
n = bin(n)
count = 0
for c in n:
if c == "1":
count += 1
return count
解法三:
十进制转二进制的方式。每次对2取余判断是否是1,是的话就count = count+1
class Solution:
def hammingWeight(self,n):
count = 0
while n:
res = n % 2
if res == 1:
count += 1
n //= 2
return count
解法四:
位运算法。
把n与1进行与运算,将得到n
的最低数字。因此可以取出最低位数,再将n
右移一位。循环此步骤,直到n
等于零。
class Solution(object):
def hammingWeight(self,n):
count = 0
while n:
count += n & 1
n >>= 1
return count
力扣784:字母大小写全排列
给定一个字符串S
,通过将字符串S
中的每个字母转变成大小写,我们可以获得一个新的字符串,返回所有可能得到的字符串集合。
示例:
输入:S = "a1b2"
输出:["a1b2","a1B2", "A1b2", "A1B2"]
输入:S = "3z4"
输出:["3z4","3Z4" ]
输入:S = "12345"
输出:["12345"]
注意:
- S 的长度不超过12
- S仅由数字和字母组成
class Slution(object):
def letterCasepermutation(self,S):
res = [S] # 无论大小写现将自身添加上去
for i in range(len(S)): # 循环
if S[i].isalpha(): #
for st in res[:]:
l = list(st)
if S[i].islower():
l[i] = S[i].upper()
res.append(''.join(l))
else:
l[i] = S[i].lower()
res.append(''.join(l))
return res