1、两数之和(Two Sum)
题目描述:
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1]
代码:
class Solution(object):
def twoSum(self,nums,target):
if len(nums)<=1:
return Flase
else:
dict={}
for i in range(len(nums)):
if nums[i] in dict:
return[dict[nums[i]],i]
else:
dict[target-nums[i]]=i# target-nums[i]为key
解析: 利用一个字典,它的key是当前遍历的值与target相差多少,value是当前值得索引。在遍历数组时候,每当遍历到一个值时就查看与target的差值在不在字典中,如果在就返回当前索引,不在就把[差值,索引]记录。
3、无重复字符的最长子串
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 :
输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其 长度为 3。
代码:
思路:用hash表来做,判断一个字母是否在表里面,不在ans就加1,在就让指针i指向最后一个出现的相同字母。维护ans的值
class Solution:
def lengthOfLongestSubstring(self, s):
"""
:type s: str
:rtype: int
"""
st={}
i,ans=0,0
for j in range(len(s)):
if s[j] in st:
i=max(st[s[j]],i)
ans=max(ans,j-i+1)
st[s[j]]=j+1
return ans
11、盛最多水的容器
给定 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
说明:你不能倾斜容器,且 n 的值至少为 2。
图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。
示例:
输入: [1,8,6,2,5,4,8,3,7] 输出: 49
代码:
思路:这道题我们用双指针,面积取决于短边,如果左指针是短边,h就是左指针,并向右移,如果右指针是短边,就用左移动。并不断维护最大值。扫一遍就够o(n)
class Solution(object):
def maxArea(self,height):
'''
:type height:List[int]
:rtype : 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=h*b
if maxarea<area:
maxarea=area
return maxarea
给定一个包含 n 个整数的数组 nums
,判断 nums
中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4], 满足要求的三元组集合为: [ [-1, 0, 1], [-1, -1, 2] ]
代码:
用left,right两边向中间搜索的方法,要注意去除重复答案。
class Solution(object):
def threeSum(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
leng=len(nums)
nums.sort()
ans=[]
for i in range(leng-2):
if i==0 or nums[i-1]<nums[i]:
l=i+1
r=leng-1
while l<r:
three_sum=nums[i]+nums[l]+nums[r]
if three_sum==0:
ans.append([nums[i],nums[l],nums[r]])
l+=1
r-=1
while l<r and nums[l]==nums[l-1]:
l+=1
while l<r and nums[r]==nums[r+1]:
r-=1
elif three_sum<0:
l+=1
else:
r-=1
return ans
给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在唯一答案。
例如,给定数组 nums = [-1,2,1,-4], 和 target = 1.
与 target 最接近的三个数的和为 2. (-1 + 2 + 1 = 2).
紧接着上一题三数之和,用相同的思路
代码如下
class Solution:
def threeSumClosest(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
nums.sort()
res = sum(nums[:3])
m = abs(res - target)
for i in range(len(nums)):
l = i+1
r = len(nums)-1
while l < r:
temp = nums[i] + nums[l] +nums[r]
if abs(res - target) > abs(temp-target):
res = temp
elif target < temp:
r -=1
else :
l +=1
return res
31、下一个排列
实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
必须原地修改,只允许使用额外常数空间。
以下是一些例子,输入位于左侧列,其相应输出位于右侧列。
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1
翻译过来:
先找出最大的索引 k 满足 nums[k] < nums[k+1],如果不存在,就翻转整个数组;
再找出另一个最大索引 l 满足 nums[l] > nums[k];
交换 nums[l] 和 nums[k];
最后翻转 nums[k+1:]。
举个例子:
比如 nums = [1,2,7,4,3,1],下一个排列是什么?
我们找到第一个最大索引是 nums[1] = 2
再找到第二个最大索引是 nums[5] = 3
交换,nums = [1,3,7,4,2,1];
翻转,nums = [1,3,1,2,4,7]
class Solution:
def nextPermutation(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
firstIndex = -1
n = len(nums)
def reverse(nums, i, j):
while i < j:
nums[i],nums[j] = nums[j], nums[i]
i += 1
j -= 1
for i in range(n-2, -1, -1):
if nums[i] < nums[i+1]:
firstIndex = i
break
#print(firstIndex)
if firstIndex == -1:
reverse(nums, 0, n-1)
return
secondIndex = -1
for i in range(n-1, firstIndex, -1):
if nums[i] > nums[firstIndex]:
secondIndex = i
break
nums[firstIndex],nums[secondIndex] = nums[secondIndex], nums[firstIndex]
reverse(nums, firstIndex+1, n-1)
32、在排序数组中查找元素的第一个和最后一个位置
描述:
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
你的算法时间复杂度必须是 O(log n) 级别。
如果数组中不存在目标值,返回 [-1, -1]。
示例 1:
输入: nums = [5,7,7,8,8,10], target = 8
输出: [3,4]
示例 2:输入: nums = [5,7,7,8,8,10], target = 6
输出: [-1,-1]
# 通过二分法找到第一个等于 target 的值, 然后以该值向左向右查找边界
def searchRange(self, nums: List[int], target: int) -> List[int]:
if not nums: return [-1, -1]
left = 0
right = len(nums) - 1
while left <= right:
mid = left + (right - left) // 2
if target < nums[mid]:
right = mid - 1
elif target > nums[mid]:
left = mid + 1
else:
left = mid
right = mid
while left - 1 >= 0 and nums[left - 1] == target:
left -= 1
while right + 1 < len(nums) and nums[right + 1] == target:
right += 1
return [left, right]
return [-1, -1]