Python刷Leetcode 数据结构与算法学习,刷题学习笔记。

`Python刷Leetcode,刷题学习笔记`

  • 一、两数之和(哈希表)
  • 二、合并两个有序数组
  • 三、爬楼梯(动态规划)

一、两数之和(哈希表)

Leetcode上的第一题,看下题目:

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。

示例:
给定: nums = [2, 7, 11, 15], target = 9
因为: nums[0] + nums[1] = 2 + 7 = 9

所以返回 [0, 1]
Python刷Leetcode 数据结构与算法学习,刷题学习笔记。_第1张图片
方法一:使用暴力求解,两个循环。

# 使用暴力解法,复杂度O(n**2)
class Solution:
    def twoSum(self, nums, target):
        for i , val in enumerate(nums):
            for j in range(i+1, len(nums)):
                if target == nums[i] + nums[j]:
                    return [i, j]

方法二:使用哈希表,类似于字典的感觉,不过要把值作为key, 索引看做value值。

class Solution:
    def twoSum(self, nums, target):
        records = {}
        for idx, val in enumerate(nums):
            # 检查键是否在
            if target - val not in records:
                records[val] = idx
            else:
                return [records[target - val], idx]

二、合并两个有序数组

题目:给你两个按非递减顺序排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。

请你合并nums2 到 nums1中,使合并后的数组同样按非递减顺序排列。
注意:最终 合并后数组不应由函数返回,而是存储在数组 nums1 中

为了应对这种情况,nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n
Python刷Leetcode 数据结构与算法学习,刷题学习笔记。_第2张图片
方法一:使用python内置的排序函数。

def merge(nums1, m, nums2, n):
    nums1[m:] = nums2
    # python内置的排序算法
    nums1.sort()
    return nums1
nums1 = [1,2,3,0,0,0]
m = 3
nums2 = [2,5,6]
n = 3
print(merge(nums1, m, nums2, n))

方法二:类似于快排了,利用两边数组有序。新建一个temp数组,取nums1和nums2的值比较大小,判断停止条件,当temp= m+n的时候。

def merge(nums1, m, nums2, n):
	k = m + n
	temp = []
	i, j = 0, 0
	while len(temp) < k:
		# 判断两个数组是否有一个用完了,需要把剩余的直接加过去
		if i >= m:
			temp.extend(nums2[j:n])
		elif j >= n:
			temp.extend(nums1[i:m])
		elif nums1[i] >= nums[j]:
			temp.append(nums2[j])
			j += 1
		else:
			temp.append(nums1[i])
			i += 1
	# 由于要求nums1不变,返回给nums1
	for i in range(len(temp)):
		nums1[i] = temp[i]

方法三:先合并两个数组,再使用快速排序

def merge(nums1, m, nums2, n):
    for i in nums2:
        nums1[m] = i
        m += 1
    def quick_sort(li):
        if len(li)<=1:
            return li
        else:
            mid = li[0]
            left_list = [x for x in li[1:] if x<=mid]
            right_list = [x for x in li[1:] if x>mid]
            # 递归调用
            return quick_sort(left_list) + [mid] + quick_sort(right_list)
    new_li = quick_sort(nums1)
    for i in range(len(new_li)):
        nums1[i] = new_li[i]

方法四:快排的另外一种写法, 定义left=0的值为tmp,比它大的移到右边,比它小的移到左边,递归调用。

def merge(nums1, m, nums2, n):
    for i in nums2:
        nums1[m] = i
        m += 1
	def partition(li, left, right):
		tmp = li[left]
		while left < right:
			while li[right] >= tmp and right > left: # 从右边找比tmp小的数
				right -= 1 # 比tmp大就往左走一步
			li[left] = li[right] # 把右边值写到左边空位
			while li[left] < tmp and left < right: # 从左边找比tmp大的数
				left += 1
			li[right] = li[left]
		li[left] = tmp
		return left
	def quick_sort(li, left, right):
		if left < right:
			mid = partition(li, left, right)
			quick_sort(li, left, mid-1)
			quick_sort(li, mid+1, right)
	quick_sort(nums1, 0, len(nums1)-1)
			

三、爬楼梯(动态规划)

题目:假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
Python刷Leetcode 数据结构与算法学习,刷题学习笔记。_第3张图片
递归的思想,一般可以考虑动态规划,
方法一: 考虑最后还剩一阶时到顶,则有一种方法,如果还剩两阶到顶则有两种方法,
递归公式:
f ( n ) = { 1 n = 1 2 n = 2 f ( n − 1 ) + f ( n − 2 ) n > 3 f(n)= \begin{cases}1 & n=1 \\ 2 & n=2 \\ f(n-1)+f(n-2) & n>3\end{cases} f(n)= 12f(n1)+f(n2)n=1n=2n>3
终止条件为最后剩一个楼梯,或者最后剩两个楼梯。

def climbStairs(n):
    # 使用递归
    if n == 1:
        return 1
    elif n == 2:
        return 2
    else:
        return climbStairs(n-1) + climbStairs(n-2)

print(climbStairs(3))

跟斐波拉契数列是一样的

#  斐波拉契数列 Fn = F(n-1) + F(n-2)
#  使用递归和非递归 1,1,2,3,5,...
def fibnacci(n):
    if n == 1 or n == 2:
        return 1
    return fibnacci(n-1) + fibnacci(n-2)

方法二:使用哈希表,将前面的值都存着。动态规划,自底向上。

# 使用哈希表加递归,动态规划,自底向上。
def climbStairs1(n):
    result = {1:1, 2:2}
    if n > 2:
        for i in range(3, n+1):
            result[i] = result.get(i, result[i-1] + result[i-2])
    return result[n]

用数组存着一样的

def climbStairs2(n):
    # 动态规划   自己写的 (本质是从下到上,)
    result = [1,2]
    if n > 2:
        for step in range(3, n+1):
            result.append(result[-1] + result[-2])
	return result[n-1]

leetcode给的答案:

def climbStairs3(n):
	s = [1,2]
	if n <= 2:
		return s[n-1]
	while len(s)<n:
		s.append(s[-1] + s[-2])
	return s[-1]

你可能感兴趣的:(挑战60天,每天Leetcode刷题,数据结构与算法,python,leetcode,学习)