新手村:
目录
1.两数之和
题目要求:
给定一个整数数组 nums
和一个整数目标值 target
,请你在该数组中找出 和为目标值 target
的那 两个 整数,并返回它们的数组下标。你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。你可以按任意顺序返回答案。
示例 1:
输入:nums = [2,7,11,15], target = 9 输出:[0,1] 解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
示例 2:
输入:nums = [3,2,4], target = 6 输出:[1,2]
示例 3:
输入:nums = [3,3], target = 6 输出:[0,1]
提示:
2 <= nums.length <= 104
-109 <= nums[i] <= 109
-109 <= target <= 109
- 只会存在一个有效答案
分析题目:
1、找到数组中和为给定目标值的的两个整数的下标
2、答案唯一,返回的下标顺序不做要求。
题解:
方法一:列表切片
根据题意一定存在满足条件的值,那么就可以依次遍历数组,然后再从剩下的值中找到满足target-i的值,最后返回他俩的下标即可。
class Solution(object):
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
#遍历整个数组
for i in range(len(nums)):
# 在i的基础上算出需要找到的目标res
res = target - nums[i]
#遍历剩下的数组
if res in nums[i+1:]:
#存在:直接返回答案。注意需要获取i后面元素中满足条件的值,而不能直接用index()
#不存在:进入下一个i
return [i,nums[i+1:].index(res)+i+1]
提交结果如下:
方法二:枚举字典
用字典的方法进行求解,使用enumerate枚举所有元素,判断字典中满足条件的值,直接返回下标,省了查找检索。
class Solution(object):
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
#定义一个空字典,用字典的k键就解决了下标的问题
records=dict()
for k,v in enumerate(nums):
#依次往字典里加值
if target-v not in records:
records[v]=k
#寻找的目标已经出现在字典中,返回下标。
else:
return[records[target-v],k]
执行结果如下:
9.回文数
题目要求:
给你一个整数 x
,如果 x
是一个回文整数,返回 true
;否则,返回 false
。
回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
- 例如,
121
是回文,而123
不是。
示例 1:
输入:x = 121 输出:true
示例 2:
输入:x = -121 输出:false 解释:从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。
示例 3:
输入:x = 10 输出:false 解释:从右向左读, 为 01 。因此它不是一个回文数。
提示:
-231 <= x <= 231 - 1
分析题目:
1、首先负数都不能满足条件
2、不需要遍历所有数组,只要让前一半等于后一半即可
解题:
方法一:双指针
将数字转换为字符串,再设计两个指针,一头一尾,然后依次往中间验证。
class Solution:
def isPalindrome(self, x: int) -> bool:
#定义两个指针,分别对应一头一尾
left , right = 0 ,len(str(x))-1
#格式化数字,将其转为列表
arr = [i for i in str(x)]
#判断左右指针当遍历一半类标后跳出循环
while left < right:
#依次判断两头的值
if arr[left] == arr[right]:
#两头指针自增
left += 1
right -= 1
else:
#不满足好像会一直False😬
return False
return True
运行结果如下:
方法二:python切片输出
直接反向输出然后验证,从思路上这个方法应该会慢一些。
class Solution:
def isPalindrome(self, x: int) -> bool:
a = str(x)
#直接用切片的反向输出
return a ==a[::-1]
运行结果如下:
每次的测试用例应该不同,有时候快、有时候慢。
方法三:数学方法-不转字符串
借鉴的其他大佬的解题思路,判断一半数字。
class Solution:
def isPalindrome(self, x: int) -> bool:
#首先剔除负数和个位数是0的整数
if x < 0 or (x != 0 and x % 10 == 0):
return False
y = 0 #设置数字反转后的值为 reverse_x ,默认为 0
while x > y: #通过 while 循环,每次循环对 x 进行取模运算, 结合余数求出每次
#循环后的倒序结果 reverse_x,当 x < reverse_x 时,结束循环
y= y* 10 + x % 10
x = x // 10
#最终判断 reverse_x 与 x 是否相等,或者 reverse_x 整除10 后的值与 x 是否相等
return x == yor x == y// 10
运行结果如下:
412.Fizz Buzz
题目要求:
给你一个整数 n
,找出从 1
到 n
各个整数的 Fizz Buzz 表示,并用字符串数组 answer
(下标从 1 开始)返回结果,其中:
answer[i] == "FizzBuzz"
如果i
同时是3
和5
的倍数。answer[i] == "Fizz"
如果i
是3
的倍数。answer[i] == "Buzz"
如果i
是5
的倍数。answer[i] == i
(以字符串形式)如果上述条件全不满足。
示例 1:
输入:n = 3 输出:["1","2","Fizz"]
示例 2:
输入:n = 5 输出:["1","2","Fizz","4","Buzz"]
示例 3:
输入:n = 15 输出:["1","2","Fizz","4","Buzz","Fizz","7","8","Fizz","Buzz","11","Fizz","13","14","FizzBuzz"]
提示:
1 <= n <= 104
分析题目:
1、合理的找出3、5、15的倍数。
2、元素要以字符串的格式输出
3、可以用字符串拼接的方法实现
解题:
方法一:if条件判断
非常好理解,对3的倍数,5的倍数,15的倍数分别做判断。
class Solution(object):
def fizzBuzz(self, n):
"""
:type n: int
:rtype: List[str]
"""
#创建空列表
lst = []
#遍历
for i in range(1,n+1):
#分别条件判断
if i % 3 == 0 and i % 5 !=0:
lst.append("Fizz")
elif i % 3!= 0 and i % 5 ==0:
lst.append("Buzz")
elif i % 15 == 0:
lst.append("FizzBuzz")
else:
lst.append(str(i))
return lst
运行结果如下:
方法二:bool拼接字符串
非常巧妙的办法,感谢原作者,利用bool值去做判断。
class Solution:
def fizzBuzz(self, n: int) -> List[str]:
# 创建空列表
lst= []
# 依次判断
for i in range(1, n + 1):
# 提前计算布尔值,减少运算
flag1,flag2 = i%3==0,i%5==0
# 使用布尔乘法 -- 非常巧妙
if flag1 or flag2:
lst.append('Fizz'*flag1+'Buzz'*flag2)
else:
lst.append(f'{i}')
return lst
876.链表的中间节点
题目要求:
给你单链表的头结点 head
,请你找出并返回链表的中间结点。
如果有两个中间结点,则返回第二个中间结点。
示例 1:
输入:head = [1,2,3,4,5] 输出:[3,4,5] 解释:链表只有一个中间结点,值为 3 。
示例 2:
输入:head = [1,2,3,4,5,6] 输出:[4,5,6] 解释:该链表有两个中间结点,值分别为 3 和 4 ,返回第二个结点。
提示:
- 链表的结点数范围是
[1, 100]
1 <= Node.val <= 100
分析题目:
1、求中间节点,首先想到的是先走一遍然后找到一共多少元素,然后再返回一半
2、快慢双指针,这么模型挺有意思的
解题:
方法一:先遍历再返回中间
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def middleNode(self, head: Optional[ListNode]) -> Optional[ListNode]:
cur = head
lenght = 0
#计算链表长度
while(cur):
lenght += 1
cur = cur.next
#取链表中间值
mid = lenght//2 + 1
mid -= 1
cur = head
#范围 从0 到 mid-1
while (mid):
cur = cur.next
mid -=1
return cur
执行结果如下:
方法二:快慢指针
重点是想到边界问题,一个是二倍速执行,如果快指针恰好执行完毕,那么链表数据个数一定是奇数然后慢指针一定在中间位置,如果快指针过界,慢指针一定在第二个中间位置。非常巧妙。
class Solution:
def middleNode(self, head: Optional[ListNode]) -> Optional[ListNode]:
fast ,slow = head ,head
#判断快指针是否经过边界
while(fast and fast.next):
fast = fast.next.next
slow = slow.next
return slow
1342.将数字变为0的操作
题目要求:
给你一个非负整数 num
,请你返回将它变成 0 所需要的步数。 如果当前数字是偶数,你需要把它除以 2 ;否则,减去 1 。
示例 1:
输入:num = 14 输出:6 解释: 步骤 1) 14 是偶数,除以 2 得到 7 。 步骤 2) 7 是奇数,减 1 得到 6 。 步骤 3) 6 是偶数,除以 2 得到 3 。 步骤 4) 3 是奇数,减 1 得到 2 。 步骤 5) 2 是偶数,除以 2 得到 1 。 步骤 6) 1 是奇数,减 1 得到 0 。
示例 2:
输入:num = 8 输出:4 解释: 步骤 1) 8 是偶数,除以 2 得到 4 。 步骤 2) 4 是偶数,除以 2 得到 2 。 步骤 3) 2 是偶数,除以 2 得到 1 。 步骤 4) 1 是奇数,减 1 得到 0 。
示例 3:
输入:num = 123 输出:12
提示:
0 <= num <= 10^6
分析题目:
1、按步骤执行,判断每一次执行后整数的奇偶
2、可以用二进制来执行
解题:
方法一:直接判断
通过奇偶直接判断,设定中间变量sum,发生一次变化,sum自增1。
class Solution(object):
def numberOfSteps(self, num):
#计数器
sum = 0
while num != 0:
#判断奇偶,分别执行
if num % 2 == 0:
num /= 2
sum += 1
else:
num -= 1
sum += 1
return sum
执行结果如下:
方法二:二进制
利用2进制 除最左边1 其余:1代表需操作两次,而0需操纵一次 例如 8:1000 解法 1出现的个数加总位数减1 即4:1+4-1
class Solution(object):
def numberOfSteps(self, num):
#将整数转换为2进制格式,使用切片取数字部分
b = bin(num)[2:]
#最左边的1只执行一次
return len(b) + b.count('1') - 1
执行结果如下:
1480.一维数组的动态和
题目要求:
给你一个数组 nums
。数组「动态和」的计算公式为:runningSum[i] = sum(nums[0]…nums[i])
。
请返回 nums
的动态和。
示例 1:
输入:nums = [1,2,3,4] 输出:[1,3,6,10] 解释:动态和计算过程为 [1, 1+2, 1+2+3, 1+2+3+4] 。
示例 2:
输入:nums = [1,1,1,1,1] 输出:[1,2,3,4,5] 解释:动态和计算过程为 [1, 1+1, 1+1+1, 1+1+1+1, 1+1+1+1+1] 。
示例 3:
输入:nums = [3,1,2,10,1] 输出:[3,4,6,16,17]
提示:
1 <= nums.length <= 1000
-10^6 <= nums[i] <= 10^6
分析题目:
1、没啥可分析的
解题:
方法一:切片
我用的切片,又写成了一行式!
class Solution(object):
def runningSum(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
# 依次遍历数组,生成新数组。
return [sum(nums[0:i+1]) for i in range(len(nums))]
运行结果如下:
方法二:遍历数组,累加求和
很好理解,没啥难度
class Solution(object):
def runningSum(self, nums):
#依次遍历
for i in range(1,len(nums)):
#每项等于前一项加自己
nums[i]+= nums[i-1]
return nums
运行结果如下:
1672.最富有客户的资产总量
题目要求:
给你一个 m x n
的整数网格 accounts
,其中 accounts[i][j]
是第 i
位客户在第 j
家银行托管的资产数量。返回最富有客户所拥有的 资产总量 。
客户的 资产总量 就是他们在各家银行托管的资产数量之和。最富有客户就是 资产总量 最大的客户。
示例 1:
输入:accounts = [[1,2,3],[3,2,1]]
输出:6
解释:
第 1 位客户的资产总量 = 1 + 2 + 3 = 6
第 2 位客户的资产总量 = 3 + 2 + 1 = 6
两位客户都是最富有的,资产总量都是 6 ,所以返回 6 。
示例 2:
输入:accounts = [[1,5],[7,3],[3,5]] 输出:10 解释:第 1 位客户的资产总量
= 6第 2 位客户的资产总量
= 10第 3 位客户的资产总量
= 8 第 2 位客户是最富有的,资产总量是 10
示例 3:
输入:accounts = [[2,8,7],[7,1,3],[1,9,5]] 输出:17
提示:
m == accounts.length
n == accounts[i].length
1 <= m, n <= 50
1 <= accounts[i][j] <= 100
分析题目:
1、二维数组,只要计算出小数组的sum,再取max即可
解题:
方法一:遍历、求和、取最大值
class Solution(object):
def maximumWealth(self, accounts):
#遍历,求和,却最大值
return max([sum(accounts[i]) for i in range(len(accounts))])
执行结果如下:
结束语:
自己是个初学者,博文中提及的方法很多也都是借鉴了其他大佬,写的目的一方面可以做学习笔记,同时希望可以帮到别人。文中难免会有疏漏之处,希望发现疏漏的朋友能热心指出其中的错误,我会及时修改,以便下次呈现再大家面前更完美更严谨。
如果有什么相关的问题,也可以关注评论留下自己的问题,我会尽量及时发送!