LeetCode部分题解(二)
1、 删除链表中的节点
请编写一个函数,使其可以删除某个链表中给定的(非末尾)节点。传入函数的唯一参数为 要被删除的节点 。
现有一个链表 – head = [4,5,1,9],它可以表示为:
示例 1:
输入:head = [4,5,1,9], node = 5
输出:[4,1,9]
解释:给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9.
示例 2:
输入:head = [4,5,1,9], node = 1
输出:[4,5,9]
解释:给定你链表中值为 1 的第三个节点,那么在调用了你的函数之后,该链表应变为 4 -> 5 -> 9.
提示:
链表至少包含两个节点。
链表中所有节点的值都是唯一的。
给定的节点为非末尾节点并且一定是链表中的一个有效节点。
不要从你的函数中返回任何结果。
之前写过一样的题,把本节点变成下一个节点,然后删除下一个节点即可
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def deleteNode(self, node):
"""
:type node: ListNode
:rtype: void Do not return anything, modify node in-place instead.
"""
node.val = node.next.val
node.next = node.next.next
2、设计停车系统
请你给一个停车场设计一个停车系统。停车场总共有三种不同大小的车位:大,中和小,每种尺寸分别有固定数目的车位。
请你实现 ParkingSystem 类:
ParkingSystem(int big, int medium, int small) 初始化 ParkingSystem 类,三个参数分别对应每种停车位的数目。
bool addCar(int carType) 检查是否有 carType 对应的停车位。 carType 有三种类型:大,中,小,分别用数字 1, 2 和 3 表示。一辆车只能停在 carType 对应尺寸的停车位中。如果没有空车位,请返回 false ,否则将该车停入车位并返回 true 。
示例 1:
输入:
[“ParkingSystem”, “addCar”, “addCar”, “addCar”, “addCar”]
[[1, 1, 0], [1], [2], [3], [1]]
输出:
[null, true, true, false, false]
解释:
ParkingSystem parkingSystem = new ParkingSystem(1, 1, 0);
parkingSystem.addCar(1); // 返回 true ,因为有 1 个空的大车位
parkingSystem.addCar(2); // 返回 true ,因为有 1 个空的中车位
parkingSystem.addCar(3); // 返回 false ,因为没有空的小车位
parkingSystem.addCar(1); // 返回 false ,因为没有空的大车位,唯一一个大车位已经被占据了
提示:
0 <= big, medium, small <= 1000
carType 取值为 1, 2 或 3
最多会调用 addCar 函数 1000 次
就是模拟整个过程,按照要求写下代码即可
class ParkingSystem:
def __init__(self, big: int, medium: int, small: int):
self.big = big
self.medium = medium
self.small = small
def addCar(self, carType: int) -> bool:
if carType == 3:
if self.small != 0:
self.small -= 1
return True
else:
return False
if carType == 2:
if self.medium != 0:
self.medium -= 1
return True
else:
return False
if carType == 1:
if self.big != 0:
self.big -= 1
return True
else:
return False
# Your ParkingSystem object will be instantiated and called as such:
# obj = ParkingSystem(big, medium, small)
# param_1 = obj.addCar(carType)
3、1108. IP 地址无效化
给你一个有效的 IPv4 地址 address,返回这个 IP 地址的无效化版本。
所谓无效化 IP 地址,其实就是用 “[.]” 代替了每个 “.”。
示例 1:
输入:address = “1.1.1.1”
输出:“1[.]1[.]1[.]1”
示例 2:
输入:address = “255.100.50.0”
输出:“255[.]100[.]50[.]0”
提示:
给出的 address 是一个有效的 IPv4 地址
这道题如果我们一个一个去遍历可能还要花点功夫,如果我们使用replace函数,就又是一个一行秒
class Solution:
def defangIPaddr(self, address: str) -> str:
return address.replace('.','[.]')
4、1678. 设计 Goal 解析器
请你设计一个可以解释字符串 command 的 Goal 解析器 。command 由 “G”、"()" 和/或 “(al)” 按某种顺序组成。Goal 解析器会将 “G” 解释为字符串 “G”、"()" 解释为字符串 “o” ,"(al)" 解释为字符串 “al” 。然后,按原顺序将经解释得到的字符串连接成一个字符串。
给你字符串 command ,返回 Goal 解析器 对 command 的解释结果。
示例 1:
输入:command = “G()(al)”
输出:“Goal”
解释:Goal 解析器解释命令的步骤如下所示:
G -> G
() -> o
(al) -> al
最后连接得到的结果是 “Goal”
示例 2:
输入:command = “G()()()()(al)”
输出:“Gooooal”
示例 3:
输入:command = “(al)G(al)()()G”
输出:“alGalooG”
提示:
1 <= command.length <= 100
command 由 “G”、"()" 和/或 “(al)” 按某种顺序组成
这道题和上道题一样,直接替换解决
class Solution:
def interpret(self, command: str) -> str:
comand = command.replace('()','o')
return comand.replace('(al)','al')
5、LCP 06. 拿硬币
桌上有 n 堆力扣币,每堆的数量保存在数组 coins 中。我们每次可以选择任意一堆,拿走其中的一枚或者两枚,求拿完所有力扣币的最少次数。
示例 1:
输入:[4,2,1]
输出:4
解释:第一堆力扣币最少需要拿 2 次,第二堆最少需要拿 1 次,第三堆最少需要拿 1 次,总共 4 次即可拿完。
示例 2:
输入:[2,3,10]
输出:8
限制:
1 <= n <= 4
1 <= coins[i] <= 10
这道题也是按照他的要求,奇数先拿一枚变偶数,偶数一次拿两枚即可
class Solution:
def minCount(self, coins: List[int]) -> int:
ans = 0
for coin in coins:
ans += int(coin / 2)
ans += coin % 2
return ans
6、1684. 统计一致字符串的数目
给你一个由不同字符组成的字符串 allowed 和一个字符串数组 words 。如果一个字符串的每一个字符都在 allowed 中,就称这个字符串是 一致字符串 。
请你返回 words 数组中 一致字符串 的数目。
示例 1:
输入:allowed = “ab”, words = [“ad”,“bd”,“aaab”,“baa”,“badab”]
输出:2
解释:字符串 “aaab” 和 “baa” 都是一致字符串,因为它们只包含字符 ‘a’ 和 ‘b’ 。
示例 2:
输入:allowed = “abc”, words = [“a”,“b”,“c”,“ab”,“ac”,“bc”,“abc”]
输出:7
解释:所有字符串都是一致的。
示例 3:
输入:allowed = “cad”, words = [“cc”,“acd”,“b”,“ba”,“bac”,“bad”,“ac”,“d”]
输出:4
解释:字符串 “cc”,“acd”,“ac” 和 “d” 是一致字符串。
提示:
1 <= words.length <= 104
1 <= allowed.length <= 26
1 <= words[i].length <= 10
allowed 中的字符 互不相同 。
words[i] 和 allowed 只包含小写英文字母。
这道题如果我们一个一个去匹配同样是比较麻烦的,所以这里我们可以用python中的集合中元素不重复的特点,只需找出所有子集即可
class Solution:
def countConsistentStrings(self, allowed: str, words: List[str]) -> int:
ans = 0
for word in words:
if set(allowed).issuperset(set(word)):
ans+=1
return ans
7、535. TinyURL 的加密与解密
TinyURL是一种URL简化服务, 比如:当你输入一个URL https://leetcode.com/problems/design-tinyurl 时,它将返回一个简化的URL http://tinyurl.com/4e9iAk.
要求:设计一个 TinyURL 的加密 encode 和解密 decode 的方法。你的加密和解密算法如何设计和运作是没有限制的,你只需要保证一个URL可以被加密成一个TinyURL,并且这个TinyURL可以用解密方法恢复成原本的URL。
这道题的判题是有些问题的,他只看加密并解密之后结果是否和之前一致,所以哪怕我们什么都不做都可以AC的,当然这道题我们也可以设计自己的密码来过,还是比较开放的
class Codec:
def encode(self, longUrl: str) -> str:
"""Encodes a URL to a shortened URL.
"""
return longUrl
def decode(self, shortUrl: str) -> str:
"""Decodes a shortened URL to its original URL.
"""
return shortUrl
# Your Codec object will be instantiated and called as such:
# codec = Codec()
# codec.decode(codec.encode(url))
8、807. 保持城市天际线
在二维数组grid中,grid[i][j]代表位于某处的建筑物的高度。 我们被允许增加任何数量(不同建筑物的数量可能不同)的建筑物的高度。 高度 0 也被认为是建筑物。
最后,从新数组的所有四个方向(即顶部,底部,左侧和右侧)观看的“天际线”必须与原始数组的天际线相同。 城市的天际线是从远处观看时,由所有建筑物形成的矩形的外部轮廓。 请看下面的例子。
建筑物高度可以增加的最大总和是多少?
例子:
输入: grid = [[3,0,8,4],[2,4,5,7],[9,2,6,3],[0,3,1,0]]
输出: 35
解释:
The grid is:
[ [3, 0, 8, 4],
[2, 4, 5, 7],
[9, 2, 6, 3],
[0, 3, 1, 0] ]
从数组竖直方向(即顶部,底部)看“天际线”是:[9, 4, 8, 7]
从水平水平方向(即左侧,右侧)看“天际线”是:[8, 7, 9, 3]
在不影响天际线的情况下对建筑物进行增高后,新数组如下:
gridNew = [ [8, 4, 8, 7],
[7, 4, 7, 7],
[9, 4, 8, 7],
[3, 3, 3, 3] ]
说明:
1 < grid.length = grid[0].length <= 50。
grid[i][j] 的高度范围是: [0, 100]。
一座建筑物占据一个grid[i][j]:换言之,它们是 1 x 1 x grid[i][j] 的长方体。
先遍历一下,把天际线找出来,然后为了不影响天际线,每个建筑都不能超过他对应的横纵天际线,换句话说,就是加上建筑物高度和对应横纵天际线的差值
class Solution:
def maxIncreaseKeepingSkyline(self, grid: List[List[int]]) -> int:
tran = [0 for i in range(len(grid[0]))]
vert = [0 for i in range(len(grid))]
for i in range(len(grid)):
for j in range(len(grid[0])):
if grid[i][j] > tran[j]:
tran[j] = grid[i][j]
if grid[i][j] > vert[i]:
vert[i] = grid[i][j]
ans = 0
for i in range(len(grid)):
for j in range(len(grid[0])):
ans += min(tran[j],vert[i]) - grid[i][j]
return ans
9、1379. 找出克隆二叉树中的相同节点
给你两棵二叉树,原始树 original 和克隆树 cloned,以及一个位于原始树 original 中的目标节点 target。
其中,克隆树 cloned 是原始树 original 的一个 副本 。
请找出在树 cloned 中,与 target 相同 的节点,并返回对该节点的引用(在 C/C++ 等有指针的语言中返回 节点指针,其他语言返回节点本身)。
注意:
你 不能 对两棵二叉树,以及 target 节点进行更改。
只能 返回对克隆树 cloned 中已有的节点的引用。
进阶:如果树中允许出现值相同的节点,你将如何解答?
示例 1
输入: tree = [7,4,3,null,null,6,19], target = 3
输出: 3
示例 2:
输入: tree = [7], target = 7
输出: 7
示例 3:
输入: tree = [8,null,6,null,5,null,4,null,3,null,2,null,1], target = 4
输出: 4
示例 4:
输入: tree = [1,2,3,4,5,6,7,8,9,10], target = 5
输出: 5
示例 5:
输入: tree = [1,2,null,3], target = 2
输出: 2
提示:
树中节点的数量范围为 [1, 10^4] 。
同一棵树中,没有值相同的节点。
target 节点是树 original 中的一个节点,并且不会是 null 。
这道题不清楚python的机制什么情况,必须要判断结点是否为空,否则找不到值,但基本的做法就是遍历,怎么遍历应该都可以,因为没有重复。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def getTargetCopy(self, original: TreeNode, cloned: TreeNode, target: TreeNode) -> TreeNode:
def f(node):
if not node:
return None
if node.val==target.val:
self.res=node
f(node.left)
f(node.right)
f(cloned)
return self.res
10、1281. 整数的各位积和之差
给你一个整数 n,请你帮忙计算并返回该整数「各位数字之积」与「各位数字之和」的差。
示例 1:
输入:n = 234
输出:15
解释:
各位数之积 = 2 * 3 * 4 = 24
各位数之和 = 2 + 3 + 4 = 9
结果 = 24 - 9 = 15
示例 2:
输入:n = 4421
输出:21
解释:
各位数之积 = 4 * 4 * 2 * 1 = 32
各位数之和 = 4 + 4 + 2 + 1 = 11
结果 = 32 - 11 = 21
提示:
1 <= n <= 10^5
把数字切割,每一位进行遍历即可
class Solution:
def subtractProductAndSum(self, n: int) -> int:
pro = 1
add = 0
while n != 0:
pro *= int(n % 10)
add += int(n % 10)
n /= 10
n = int(n)
return int(pro - add)
11、1389. 按既定顺序创建目标数组
给你两个整数数组 nums 和 index。你需要按照以下规则创建目标数组:
目标数组 target 最初为空。
按从左到右的顺序依次读取 nums[i] 和 index[i],在 target 数组中的下标 index[i] 处插入值 nums[i] 。
重复上一步,直到在 nums 和 index 中都没有要读取的元素。
请你返回目标数组。
题目保证数字插入位置总是存在。
示例 1:
输入:nums = [0,1,2,3,4], index = [0,1,2,2,1]
输出:[0,4,1,3,2]
解释:
nums index target
0 0 [0]
1 1 [0,1]
2 2 [0,1,2]
3 2 [0,1,3,2]
4 1 [0,4,1,3,2]
示例 2:
输入:nums = [1,2,3,4,0], index = [0,1,2,3,0]
输出:[0,1,2,3,4]
解释:
nums index target
1 0 [1]
2 1 [1,2]
3 2 [1,2,3]
4 3 [1,2,3,4]
0 0 [0,1,2,3,4]
示例 3:
输入:nums = [1], index = [0]
输出:[1]
提示:
1 <= nums.length, index.length <= 100
nums.length == index.length
0 <= nums[i] <= 100
0 <= index[i] <= i
python写这个题比较无脑,直接insert按要求填入参数即可
class Solution:
def createTargetArray(self, nums: List[int], index: List[int]) -> List[int]:
target = []
for i in range(len(nums)):
target.insert(index[i],nums[i])
return target
12、1313. 解压缩编码列表
给你一个以行程长度编码压缩的整数列表 nums 。
考虑每对相邻的两个元素 [freq, val] = [nums[2i], nums[2i+1]] (其中 i >= 0 ),每一对都表示解压后子列表中有 freq 个值为 val 的元素,你需要从左到右连接所有子列表以生成解压后的列表。
请你返回解压后的列表。
示例:
输入:nums = [1,2,3,4]
输出:[2,4,4,4]
解释:第一对 [1,2] 代表着 2 的出现频次为 1,所以生成数组 [2]。
第二对 [3,4] 代表着 4 的出现频次为 3,所以生成数组 [4,4,4]。
最后将它们串联到一起 [2] + [4,4,4] = [2,4,4,4]。
示例 2:
输入:nums = [1,1,2,3]
输出:[1,3,3]
提示:
2 <= nums.length <= 100
nums.length % 2 == 0
1 <= nums[i] <= 100
这道题直接遍历然后按照要求把数字压入ans数组然后返回即可
class Solution:
def decompressRLElist(self, nums: List[int]) -> List[int]:
ans = []
for i in range(0,len(nums),2):
for j in range(nums[i]):
ans.append(nums[i+1])
return ans