面试题 两数之和
题目描述:给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
解题思路:创建一个空字典,依次把target-nums[x]的值存入字典,存入一个就跟nums[x+1]去比较, 字典中的key为target-nums[x],value为x,也就是nums[x]在nums列表中的索引位置
代码
class Solution(object):
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
n = len(nums)
d = {}
for x in range(n):
a = target - nums[x]
if nums[x] in d:
return d[nums[x]],x
else:
d[a] = x
面试题: 整数反转
题目描述:给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。
解题思路:考虑三种情况—正数 负数 超出范围溢出
代码:
class Solution(object):
def reverse(self, x):
"""
:type x: int
:rtype: int
"""
ret = 0
t = abs(x)
while t:
ret = ret*10 + t%10
t /= 10
if ret > 2 ** 31 or -ret < -2 ** 31:
return 0
return ret if x >= 0 else -ret
面试题:N个数中找出第k个最大的数----选择问题[腾讯视频技术面编程题]
解题思路 先排序再找第K大数or部分排序or借助数据结构堆
代码
# 方法1 冒泡递减排序,然后返回位置k上的数据 时间复杂度O(N^2)
def findK(nums,k):
for i in range(len(nums)):
for j in range(len(nums) - i- 1):
if (nums[j] > nums[j + 1]):
nums[j],nums[j +1] = nums[j + 1], nums[j]
return nums[len(nums) - k]
print(findK([2,1,6,5,3,0,8], 1)) # 8
# 冒泡改进 部分元素排序,k比较小时,只需要排序最大的k个元素即可,即在冒泡排序中只进行k趟起泡,时间复杂度为O(N*k)
def findK(nums, k):
flag = True
for i in range(k):
flag = False
for j in range(len(nums) - i - 1):
if (nums[j] > nums[j + 1]):
nums[j],nums[j +1] = nums[j + 1], nums[j]
flag = True
if (not flag):
break
return nums[len(nums)-k]
#print(findK([2,1,6,5,3,0,8], 7))
# 基于快排
def findKthLargest(nums, k):
return findK(nums,k,0,len(nums) - 1)
def findK(nums,k,start,end):
low = start
high = end
temp = nums[low]
while(low < high):
while(low
high -= 1
nums[low] = nums[high]
while(low= temp):
low += 1
nums[high] = nums[low]
nums[high] = temp
if(high == k-1):
return temp
elif(high > k -1):
return findK(nums,k,start,high-1)
else:
return findK(nums,k,high+1,end)
print(findKthLargest([2,1,6,5,3,0,8],7))
#方法 时间复杂度O(N)
def find_k(test_list,k):
flag=test_list[0]
test_list.pop(0)
l_list=[i for i in test_list if i < flag]
r_list=[i for i in test_list if i >= flag]
#结果递归的基线条件
if len(r_list)==k-1:
return flag
elif len(r_list)>k-1:
return find_k(r_list,k)
else:
#因为test_list.pop(0)让test_list少了一个元素,所以下面需要+1
gap=len(test_list)-len(l_list)+1
k=k-gap
return find_k(l_list,k)
print(find_k([2,1,6,5,3,0,8],1))
#方法 堆
import heapq
class Solution:
def findKthLargest(self, nums: [int], k: int) -> int:
heap = []
for num in nums[:k]:
heapq.heappush(heap, num)
for num in nums[k:]:
if num > heap[0]:
heapq.heappop(heap)
heapq.heappush(heap, num)
return heap[0]
s=Solution()
print(s.findKthLargest([2,1,6,5,3,0,8],2))
面试题:旋转数组的最小数字
题目描述:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转,该数组的最小值为1。
示例 1:
输入:[3,4,5,1,2]
输出:1
示例 2:
输入:[2,2,2,0,1]
输出:0
解题思路:二分查找
举例 每次和right比
初始序列是34512:
345 12:此时mid > right 就left = mid+1
12:此时mid < right 就right = mid
1:此时left = right 找到了,返回
但是出现重复数字时二分查找不管用
举例 每次和right比
初始序列是11101:
11101:此时mid = right,right = right - 1
1110:此时mid > right ,left = mid+1
10:此时mid > right ,left = mid+1
0:找到目标最小值
代码:
class Solution(object):
def minArray(self, numbers):
"""
:type numbers: List[int]
:rtype: int
"""
low, hight = 0, len(numbers) - 1
while low < hight:
mid = (low + hight) / 2
if numbers[mid] > numbers[hight]: low = mid + 1
elif numbers[mid] < numbers[hight]: hight = mid
else: hight -= 1
return numbers[hight]
面试题:移动零
题目描述:给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
示例:
输入: [0,1,0,3,12]
输出: [1,3,12,0,0]
说明:
必须在原数组上操作,不能拷贝额外的数组。
尽量减少操作次数。
解题思路:快慢指针
代码:
class Solution(object):
def moveZeroes(self, nums):
"""
:type nums: List[int]
:rtype: None Do not return anything, modify nums in-place instead.
"""
fast = 0
low = 0
for i in range(len(nums)):
if nums[i] == 0:
fast += 1
else:
nums[low] = nums[fast]
low += 1
fast += 1
for i in range(low, len(nums)):
nums[i] = 0