(题目源自leetcode,方法都是自(cai)己(ji)写的,可能比较符合菜鸡们的思路)
1.删除排序数组中的重复项
给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
示例 1:
给定数组 nums = [1,1,2],
函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。
你不需要考虑数组中超出新长度后面的元素。
class Solution:
def removeDuplicates(self, nums: List[int]) -> int:
a=0
b=1
amount = 1
if len(nums)==0:
return 0
while b<len(nums):
if nums[a]==nums[b]:
b=b+1
else:
a=a+1
nums[a]=nums[b]
b=b+1
amount += 1
return amount
使用双指针,a记录重复的需要更改的位置。b后移,遇到不同的元素,则对a位置的重复元素进行覆盖。
2.买卖股票的最佳时机 II
给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
示例 1:
输入: [7,1,5,3,6,4]
输出: 7
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。
class Solution:
def maxProfit(self, prices: List[int]) -> int:
profit = 0
for i in range(1,len(prices)):
profit += max(0,prices[i]-prices[i-1])
return profit
每一天比前一天高的价格均为利润
3.旋转数组
给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
示例 1:
输入: [1,2,3,4,5,6,7] 和 k = 3
输出: [5,6,7,1,2,3,4]
解释:
向右旋转 1 步: [7,1,2,3,4,5,6]
向右旋转 2 步: [6,7,1,2,3,4,5]
向右旋转 3 步: [5,6,7,1,2,3,4]
class Solution:
def rotate(self, nums: List[int], k: int) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
k = k%len(nums)
while k > 0:
nums.insert(0,nums.pop())
k = k - 1
数组每pop一个,就insert到前面。
4.存在重复元素
给定一个整数数组,判断是否存在重复元素。
如果任意一值在数组中出现至少两次,函数返回 true 。如果数组中每个元素都不相同,则返回 false 。
示例 1:
输入: [1,2,3,1]
输出: true
class Solution:
def containsDuplicate(self, nums: List[int]) -> bool:
return len(nums)!=len(set(nums))
转set去掉重复元素,与原列表长度不想等,说明重复了
5.只出现一次的数字
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
示例 1:
输入: [2,2,1]
输出: 1
class Solution:
def singleNumber(self, nums: List[int]) -> int:
nums.sort()
for i in range(len(nums)//2+1):
if 2*i==len(nums)-1:
return nums[2*i]
if nums[2*i]!=nums[2*i+1]:
return nums[2*i]
排序后,第一个奇数位与后位不相同的,即为只出现一次的数字。
class Solution:
def singleNumber(self, nums: List[int]) -> int:
return sum(set(nums))*2-sum(nums)
一行代码,转set的和双倍减去原列表的和
6.两个数组的交集 II
给定两个数组,编写一个函数来计算它们的交集。
示例 1:
输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2,2]
class Solution:
def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]:
small = nums1 if len(nums1)<len(nums2) else nums2
big = nums2 if len(nums1)<len(nums2) else nums1
out = []
for i in range(len(small)):
if small[i] in big:
out.append(small[i])
big.remove(small[i])
return out
先找出较小的列表small,然后拿small的元素去big比较,重复则在输出里加入该元素,并把big中的删除,避免重复。
7.加一
给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。
最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。
你可以假设除了整数 0 之外,这个整数不会以零开头。
示例 1:
输入:digits = [1,2,3]
输出:[1,2,4]
解释:输入数组表示数字 123。
class Solution:
def plusOne(self, digits: List[int]) -> List[int]:
digits[-1] += 1
for i in range(len(digits)-1,0,-1):
if digits[i]==10:
digits[i]=0
digits[i-1]+=1
if digits[0]==10:
digits[0]=0
digits.insert(0,1)
return digits
挨位判断加一是否为10,10则转0进位
最后看第一位是不是10,是的话,补位。
8.移动零
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
示例:
输入: [0,1,0,3,12]
输出: [1,3,12,0,0]
class Solution:
def moveZeroes(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
num = 0
while num in nums:
nums.remove(0)
num = num + 1
while num > 0:
nums.append(0)
num = num-1
return nums
先检查0,有的话就remove并记录次数,最后在列表末尾补上。
也可以双指针,后面不为0的和前面为0的互换。
9.两数之和
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
#nums.sort()
for num in nums:
if (target-num) in nums and (idx1:=nums.index(num))!= (idx2:=nums.index(target-num)):
return [idx1,idx2]
遍历列表中的元素num,如果num和target-num都在列表中,且两者的index不同,则返回。
10.有效的数独
判断一个 9x9 的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可。
数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
class Solution:
def isValidSudoku(self, board: List[List[str]]) -> bool:
rows, columns, boxes = defaultdict(set), defaultdict(set), defaultdict(set)
for row in range(9):
for col in range(9):
if board[row][col]=='.':
continue
if board[row][col] in rows[row]:
return False
if board[row][col] in columns[col]:
return False
if board[row][col] in boxes[(row//3)*3+col//3]:
return False
rows[row].add(board[row][col])
columns[col].add(board[row][col])
boxes[(row//3)*3+col//3].add(board[row][col])
return True
defaultdict(set)???待补充
遍历元素,检查是否符合条件,不符合条件则返回False
11.旋转图像
给定一个 n × n 的二维矩阵表示一个图像。
将图像顺时针旋转 90 度。
说明:
你必须在原地旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要使用另一个矩阵来旋转图像。
示例 1:
给定 matrix =
[
[1,2,3],
[4,5,6],
[7,8,9]
],
原地旋转输入矩阵,使其变为:
[
[7,4,1],
[8,5,2],
[9,6,3]
]
class Solution:
def rotate(self, matrix: List[List[int]]) -> None:
"""
Do not return anything, modify matrix in-place instead.
"""
n = len(matrix[0])
col = defaultdict(list)
for i in range(n):
for j in range(n):
col[j].append(matrix[i][j])
for r in range(n):
for c in range(n):
matrix[r][n-c-1]=col[r][c]
两次遍历,第一次复制列,第二次遍历,根据规律在原列表上赋值。
class Solution:
def rotate(self, matrix: List[List[int]]) -> None:
matrix[:] = zip(*reversed(matrix))
大佬一行解法,reversed???待补充