26.删除数组中的重复项 5.20
给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。
class Solution(object):
def removeDuplicates(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if len(nums)<=1:
return len(nums)
else:
count=0
for value in nums:
if value> nums[count]:
count+=1
nums[count] = value
return count+1
35.搜索插入位置 5.20
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
class Solution(object):
def searchInsert(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
for index in range(len(nums)):
if nums[index]==target:
return index
elif nums[index]>target:
return index
elif index==len(nums)-1:
return len(nums)
## 二分法
class Solution(object):
def searchInsert(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
left = 0
right = len(nums)-1
while left <= right:
mid = (right - left) / 2 + left
if nums[mid] == target:
return mid
elif nums[mid] > target:
right = mid - 1
else:
left = mid + 1
return left
53.最大子序和 5.21
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
这道题跟之前网易面试的股票买卖问题类似,采用的叫Kadane’s Algorithm的方法,用两个指针。maxSum指针记录此前所有碰到的最大值,curSum指针记录循环到当前元素这一轮的最大值。当循环到元素i时,如果i+curSum < i的话,说明此前的和是负的,需要舍弃,所以将curSum的值变为i,反之,将curSum的值变为i+curSum,表明当前的和还是正值,可以继续向前探索(max(cursum,cursum+i)),由于每一次遍历一个元素之后都会比较一下curSum和maxSum,所以可以放心的继续向前遍历。
- attention: 注意数组元素个数为1 的情况。
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
maxsum = nums[0]
cursum = nums[0]
for i in nums[1:]:
cursum = max(cursum+i,i)
maxsum = max(maxsum,cursum)
return maxsum
66.加一 5.21
给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一。
最高位数字存放在数组的首位, 数组中每个元素只存储一个数字。你可以假设除了整数 0 之外,这个整数不会以零开头。
示例:
输入: [1,2,3]
输出: [1,2,4]
解释: 输入数组表示数字 123。
这一题容易陷入原始计算+1的情况,即需要检测每一位在加1之后是否出现进一位的情况,那跳脱这种思维方式的话,可以直接通过int和str的转换得到最终结果。
class Solution:
def plusOne(self, digits: List[int]) -> List[int]:
num = 0
for value in digits:
num = num*10 + value
return [int(x) for x in str(num+1)]
88. 合并两个有序数组 5.23 (⚠️)
给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组。
说明:
初始化 nums1 和 nums2 的元素数量分别为 m 和 n。
你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。
借鉴优秀解法:为了提高计算效率,减少数组元素的移动,对两个数组arr1,arr2从后往前遍历,对每次选中的元素做比较,取较大的元素存入arr1中。这里做遍历的条件是m>0,n>0,所以可能会出现某列元素先遍历完的情况,这时就得看arr2的n是否归0,若没有的话,得将arr1的前n个元素与arr2的前n个元素做替换。
class Solution:
def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
while m > 0 and n > 0:
if nums1[m - 1] > nums2[n - 1]:
nums1[m + n - 1] = nums1[m - 1]
m = m - 1
else:
nums1[m + n - 1] = nums2[n - 1]
n = n - 1
if n > 0:
nums1[:n] = nums2[:n]
118.杨辉三角 pascal’s triangle 5.27(⚠️)
给定一个非负整数 numRows,生成杨辉三角的前 numRows 行。
简单粗暴的解题方法是计算每一行的数,这需要去分rownums<=2以及rownums>2的情况。一种比较巧妙的方式是:计算当前row的数值之前将上一个row的向量
a
r
r
i
−
1
arr_{i-1}
arri−1首尾分别补0后相加,即[0,
a
r
r
i
−
1
]
+
[
a
r
r
i
−
1
,
0
]
arr_{i-1}]+[arr_i-1,0]
arri−1]+[arri−1,0](对应元素相加)。
⚠️python的向量加法与元素相加
python自带的list类型之间相加是往list内添加元素,例如:[0]+[1] -> [0 1]
numpy 却可以实现向量的元素之间的相加;
class Solution(object):
def generate(self, numRows):
"""
:type numRows: int
:rtype: List[List[int]]
"""
if numRows == 0:return []
res = [[1]]
for i in range(1,numRows):
res.append(list(map(lambda x,y:x+y,res[-1]+[0],[0]+res[-1])))
return res
其中利用lambda和map实现了元素之间的相加~