【程序人生】leetcode(二)
说在前面
这篇博客中部分题目答案来自leetcode评论区,不是本人原创。感谢原作者的工作。这里记录在这篇博客中,方便日后回顾、学习
罗马数字转整数(原创)
罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。
字符 | 数值 |
---|---|
I | 1 |
V | 5 |
X | 10 |
L | 50 |
C | 100 |
D | 500 |
M | 1000 |
例如, 罗马数字2写做II,即为两个并列的1。12写做XII,即为X+II。 27写做XXVII, 即为XX+V+II。
通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如4不写做IIII,而是IV。数字1在数字5的左边,所表示的数等于大数5减小数1得到的数值4。同样地,数字9表示为IX。这个特殊的规则只适用于以下六种情况:
- I可以放在V(5)和X (10)的左边,来表示4和9。
- X可以放在L(50)和C(100)的左边,来表示40和90。
- C可以放在D(500)和M(1000)的左边,来表示400和900。
给定一个罗马数字,将其转换成整数。输入确保在 1 到 3999 的范围内。
class Solution:
def romanToInt(self, s: str) -> int:
hash_map = {"I":1, "V":5, "X":10, "L":50, "C":100, "D":500, "M":1000}
value = 0
s = list(s[::-1])
for i, each in enumerate(s):
if i == 0:
value = value + hash_map[each]
else:
if hash_map[each] >= hash_map[s[i-1]]:
value = value + hash_map[each]
else:
value = value - hash_map[each]
return value
整数转罗马数字(转载)
罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。
字符 | 数值 |
---|---|
I | 1 |
V | 5 |
X | 10 |
L | 50 |
C | 100 |
D | 500 |
M | 1000 |
例如, 罗马数字2写做II,即为两个并列的1。12写做XII,即为X+II。 27写做XXVII, 即为XX+V+II。
通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如4不写做IIII,而是IV。数字1在数字5的左边,所表示的数等于大数5减小数1得到的数值4。同样地,数字9表示为IX。这个特殊的规则只适用于以下六种情况:
- I可以放在V(5)和X (10)的左边,来表示4和9。
- X可以放在L(50)和C(100)的左边,来表示40和90。
- C可以放在D(500)和M(1000)的左边,来表示400和900。
给定一个整数,将其转为罗马数字。输入确保在1到3999的范围内。
class Solution:
def intToRoman(self, num: int) -> str:
hash_map = {"M":1000, "CM":900, "D":500, "CD":400, "C":100, "XC":90,
"L":50, "XL":40, "X":10, "IX":9, "V":5, "IV":4, "I":1}
string = ""
while num>0:
for key in hash_map:
while num>=hash_map[key]:
num-=hash_map[key]
string +=key
return string
盛水最多的容器(转载)
给你n个非负整数 a 1 a_1 a1, a 2 a_2 a2,…, a n a_n an,每个数代表坐标中的一个点 ( i , a i ) (i, a_i) (i,ai)。在坐标内画n条垂直线,垂直线i的两个端点分别为 ( i , a i ) (i, a_i) (i,ai)和 ( i , 0 ) (i, 0) (i,0)。找出其中的两条线,使得它们与x轴共同构成的容器可以容纳最多的水。
说明:你不能倾斜容器,且n的值至少为 2。
图中垂直线代表输入数组[1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为49。
class Solution:
def maxArea(self, height: List[int]) -> int:
left = 0
right = len(height) - 1
maxArea = 0
while left < right:
b = right - left
if height[left] < height[right]:
h = height[left]
left += 1
else:
h = height[right]
right -= 1
area = b*h
if maxArea < area:
maxArea = area
return maxArea
三数之和(转载)
给你一个包含n个整数的数组nums,判断nums中是否存在三个元素a,b,c,使得a + b + c = 0?请你找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
# 升序排列
nums.sort()
res =[]
for i in range(len(nums)):
if i == 0 or nums[i]>nums[i-1]:
l = i+1
r = len(nums)-1
while l < r:
s = nums[i] + nums[l] +nums[r]
if s == 0:
res.append([nums[i],nums[l],nums[r]])
l += 1
r -= 1
while l < r and nums[l] == nums[l-1]:
l += 1
while r > l and nums[r] == nums[r+1]:
r -= 1
elif s > 0:
r -= 1
else :
l += 1
return res
- 将数组排序
- 定义三个指针,i、j、k。遍历i,那么这个问题就可以转化为在i之后的数组中寻找 n u m s [ j ] + n u m s [ k ] = − n u m s [ i ] nums[j]+nums[k]=-nums[i] nums[j]+nums[k]=−nums[i]这个问题,也就将三数之和问题转变为二数之和
合并两个有序链表(原创)
将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
if l1 is None:
return l2
if l2 is None:
return l1
# 遍历a, 插入start
if l1.val >= l2.val:
a = l1
start = l2
else:
a = l2
start = l1
node = start
while a is not None:
try:
while not (node.val <= a.val <= node.next.val):
node = node.next
linshi = ListNode(a.val)
linshi.next = node.next
node.next = linshi
except AttributeError:
node.next = a
return start
a = a.next
return start
电话号码的字母组合(原创)
给定一个仅包含数字2-9的字符串,返回所有它能表示的字母组合。
给出数字到字母的映射如下(与电话按键相同)。注意1不对应任何字母。
class Solution:
def letterCombinations(self, digits: str) -> List[str]:
hash_map = {2:["a", "b", "c"], 3:["d", "e", "f"],
4:["g", "h", "i"], 5:["j", "k", "l"],
6:["m", "n", "o"], 7:["p", "q", "r", "s"],
8:["t", "u", "v"], 9:["w", "x", "y", "z"]}
num = len(digits)
result = []
while num > 0:
key = int(digits[0:1])
digits = digits[1:]
num = len(digits)
if result == []:
for each in hash_map[key]:
result.append(each)
else:
res = []
for i in result:
for j in hash_map[key]:
res.append(i+j)
result = res
return result
两两交换链表中的节点(转载)
给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
示例:
给定 1->2->3->4, 你应该返回 2->1->4->3.
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def swapPairs(self, head: ListNode) -> ListNode:
if (head is None) or (head.next is None):
return head
linshi = ListNode(head.next.val)
linshi.next = head
head.next = self.swapPairs(head.next.next)
return linshi
使用递归来解决该题,主要就是递归的三部曲:
- 找终止条件:本题终止条件很明显,当递归到链表为空或者链表只剩一个元素的时候,没得交换了,自然就终止了。
- 找返回值:返回给上一层递归的值应该是已经交换完成后的子链表。
- 单次的过程:因为递归是重复做一样的事情,所以从宏观上考虑,只用考虑某一步是怎么完成的。我们假设待交换的俩节点分别为head和next,next的应该接受上一级返回的子链表(参考第2步)。就相当于是一个含三个节点的链表交换前两个节点,就很简单了,想不明白的画画图就ok。
括号生成(转载)
数字n代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且有效的括号组合。
示例:
输入:n = 3
输出:[
“((()))”,
“(()())”,
“(())()”,
“()(())”,
“()()()”
]
class Solution:
def generateParenthesis(self, n: int) -> List[str]:
result = []
def dfs(num_left, num_right, string):
if num_left == 0 and num_right == 0:
result.append(string)
return
if num_left > 0:
dfs(num_left - 1, num_right, string + "(")
if num_right > num_left:
dfs(num_left, num_right - 1, string + ")")
dfs(n, n, "")
return result
有效的括号(转载)
给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。
class Solution:
def isValid(self, s: str) -> bool:
while (("[]" in s) or ("()" in s) or ("{}" in s)):
s = s.replace("[]", "")
s = s.replace("()", "")
s = s.replace("{}", "")
if s == "":
return True
else:
return False
最接近的三数之和(原创)
给定一个包括n个整数的数组nums和一个目标值target。找出nums中的三个整数,使得它们的和与target最接近。返回这三个数的和。假定每组输入只存在唯一答案。
示例:
例如,给定数组 nums = [-1,2,1,-4], 和 target = 1.
与 target 最接近的三个数的和为 2. (-1 + 2 + 1 = 2).
class Solution:
def threeSumClosest(self, nums: List[int], target: int) -> int:
# 判断是不是最接近target
res = 1000000000000000000
# 返回结果
result = 0
# 升序排列
nums.sort()
for i, each in enumerate(nums[:-2]):
linshi = nums[i+1:]
# 左指针
p1 = 0
# 右指针
p2 = len(linshi) - 1
if abs(each + linshi[p1] + linshi[p2] - target) == 0:
return each + linshi[p1] + linshi[p2]
if abs(each + linshi[p1] + linshi[p2] - target) < res:
result = each + linshi[p1] + linshi[p2]
res = abs(each + linshi[p1] + linshi[p2] - target)
while p1 < p2:
if (each + linshi[p1] + linshi[p2] - target) == 0:
return each + linshi[p1] + linshi[p2]
if abs(each + linshi[p1] + linshi[p2] - target) < res:
result = each + linshi[p1] + linshi[p2]
res = abs(each + linshi[p1] + linshi[p2] - target)
if (each + linshi[p1] + linshi[p2] - target) > 0:
p2 = p2 -1
else:
p1 = p1 + 1
return result
结语
如果您有修改意见或问题,欢迎留言或者通过邮箱和我联系。
手打很辛苦,如果我的文章对您有帮助,转载请注明出处。