算法刷题笔记

排序
在这里插入图片描述

  1. 快速排序 快排
    时间复杂度:O(nlogn)空间复杂度:O(1)
    不稳定
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
# 将给定数组排序
# @param arr int整型一维数组 待排序的数组
# @return int整型一维数组
#
class Solution:
    def MySort(self , arr ):
        # write code here
        self.quick_sort(0, len(arr)-1, arr)
        return arr

    def quick_sort(self, start, end, arr):
        if start >= end:
            return

        left, right = start, end
        pivot = arr[(start + end)//2]

        while left <= right:
            while left <= right and arr[left] < pivot:
                left += 1
            while left <= right and arr[right] > pivot:
                right -= 1

            if left <= right:
                arr[left], arr[right] = arr[right], arr[left]
                left += 1
                right -= 1

        self.quick_sort(start, right, arr)
        self.quick_sort(left, end, arr)
  1. 冒泡排序
    一对一对的比较 反复loop
    367219 - 362179 - 321679 - 213679 - 123679

时间复杂度:O(n^2)空间复杂度:O(1)

  1. 选择排序
    选一个最大或最小值放在起始位,不断loop后面的找到最值,更新在后面的位置
    367219 - 167239 - 127639 - 123679

时间复杂度:O(n^2)空间复杂度:O(1)

  1. 插入排序
    每次把当前元素跟前面排好的相比,不断地swap到应该在的地方
    367219 - 236719 - 123679

时间复杂度:O(n^2)空间复杂度:O(1)

  1. 归并排序
    时间复杂度:O(nlogn)空间复杂度:O(1)
    稳定
  2. 堆排序
    时间复杂度:O(nlogn)空间复杂度:O(1)
    不稳定
class Solution:
    def MySort(self , arr ):
        # write code here
#         return self.bubble_sort(arr)
#         return self.select_sort(arr)
#         return self.insert_sort(arr)
        return self.quick_sort(arr)
#         return self.merge_sort(arr)
         
    def bubble_sort(self, arr):
        # 冒泡排序 不通过
        for i in range(len(arr) - 1):
            for j in range(len(arr) - i - 1):
                if arr[j] > arr[j+1]:
                    arr[j], arr[j+1] = arr[j+1], arr[j]
        return arr
       
    def select_sort(self, arr):
        # 选择排序 不通过
        for i in range(len(arr)):
            min_index = i
            for j in range(i+1, len(arr)):
                if arr[j] < arr[min_index]:
                    min_index = j
            arr[min_index], arr[i] = arr[i], arr[min_index]
        return arr
    
    def insert_sort(self, li):
        # 插入排序 不通过
        for i in range(1, len(li)):
            tmp = li[i]                     # tmp要插入的之
            j = i - 1
            while j >= 0 and li[j] > tmp:   # 前面的值比tmp大
                li[j+1] = li[j]             # 前面的值向后移一位
                j = j - 1                   # 继续向前对比
            li[j+1] = tmp                   # 直到while不满足条件, 也就是前面的值比tmp小, 插入到比tmp小的值后
        return li
    
    def quick_sort(self, li):
        # 快速排序 通过
        if len(li) < 2:
            return li
        else:
            tmp = li[0]
            less = [i for i in li[1:] if i <= tmp]
            more = [i for i in li[1:] if i > tmp]
            return self.quick_sort(less) + [tmp] + self.quick_sort(more)
        
    def merge_sort(self, li):
        # 归并排序 可能通过 可能不通过
        if len(li) < 2:
            return li
        else:
            num = len(li) // 2
            left = self.merge_sort(li[:num])
            right = self.merge_sort(li[num:])
            return self.merge(left, right)
        
    def merge(self, left, right):
        l,r = 0,0
        result = []
        while l < len(left) and r < len(right):
            if left[l] < right[r]:
                result.append(left[l])
                l += 1
            else:
                result.append(right[r])
                r += 1
        result += left[l:]
        result += right[r:]
        return result

反转链表
在这里插入图片描述
假设 链表为 1->2->3->4->null 空就是链表的尾
obj: 4->3->2->1->null
那么逻辑是
首先设定待反转链表的尾 pre = none
head 代表一个动态的表头 逐步取下一次链表的值
然后利用temp保存 head.next 第一次迭代head为1 temp 为2 原始链表中是1->2
现在我们需要翻转 即 令head.next = pre 实现 1->none
但此时链表切断了 变成了 1->none 2->3->4
所以我们要移动指针,另pre = head 也就是pre从none 变成1 下一次即可完成2->1的链接
此外另head = next 也就是说 把指针移动到后面仍然链接的链表上
这样执行下一次循环 则实现 把2->3 转变为 2->1->none
然后再次迭代
直到最后一次 head 变成了none 而pre变成了4 则pre是新的链表的表头
完成翻转

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    # 返回ListNode
    def ReverseList(self, pHead):
        # write code here
        pre = None
        head = pHead
        while head:
            temp = head.next
            head.next = pre 
            pre = head 
            head = temp 
        return pre 

LRU缓存结构
在这里插入图片描述
二维数组中第0位即:[1,1,1],第一个1表示opt=1,要set(1,1),即要将(1,1)插入缓存
二维数组中第1为即:[1,2,2],第一个1表示opt=1,要set(2,2),即要将(2,2)插入缓存
二维数组中第2位即:[1,3,2],第一个1表示opt=1,要set(3,2),即要将(3,2)插入缓存
二维数组中第3位即:[2,1],第一个2表示opt=2,要get(1),即从缓存中查找key为1的值,前面已经插入了key=1,所以返回1,这个要保存到返回数组中
二维数组中第5位即:[2,2],第一个2表示opt=2,要get(2),即从缓存中查找key为2的值,由于缓存大小为3,所以前面插入的key=2已经被挤出缓存,所以返回结果为-1,这个要保存到返回数组中
所以输出为[1,-1]
示例1中,输入最后一个单独的3表示缓存大小

# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# lru design
# @param operators int整型二维数组 the ops
# @param k int整型 the k
# @return int整型一维数组
#
class Solution:
    def LRU(self , operators: List[List[int]], k: int) -> List[int]:
        # write code here
        stack = []
        res = []
        lru = {}
        for op in operators:
            if(op[0] == 1):
                if(len(stack) >= k):
                    del lru[stack.pop(0)]
                if(op[1] in lru):
                    stack.pop(stack.index(op[1]))
                stack.append(op[1])
                lru[op[1]] = op[2]
            elif(op[0] == 2):
                if(op[1] not in lru):
                    res.append(-1)
                else:
                    res.append(lru[op[1]])
                    stack.append(stack.pop(stack.index(op[1])))
        return res

加入的时候判断内存是否溢出
get的时候判断dict.keys()

class Solution:
    def LRU(self , operators , k ):
        A,a=dict(),[]
        def set(key,value):
            if len(a)<k: 
                A[key]=value 
                a.append(key) 
            else: 
                del A[a.pop(0)] 
                A[key]=value
                a.append(key) 

        def get(key):
            if key in A.keys(): 
                a.remove(key)
                a.append(key)
                return A[key] 
            else: return -1 

        sol=[]
        for i in operators:
            if i[0]==1: set(i[1],i[2])
            else: 
                sol.append(get(i[1]))
        return sol
        # write code here

遍历
在这里插入图片描述
输入:
{1,2,3}
返回值:
[[1,2,3],[2,1,3],[2,3,1]]

# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param root TreeNode类 the root of binary tree
# @return int整型二维数组
#
class Solution:
    def threeOrders(self , root: TreeNode) -> List[List[int]]:
        # write code here
        return [self.front(root), self.middle(root), self.back(root)]
    
    def front(self, root, var=None):
        if root is None:
            return    # 终止递归
        if var is None:
            var = []    # 开始递归,初始化结果存储列表
        var.append(root.val)
        lt = self.front(root.left, var)
        rt = self.front(root.right, var)
        return var
        
    
    def middle(self, root, var=None):
        if root is None:
            return
        if var is None:
            var = []
        lt = self.middle(root.left, var)
        var.append(root.val)
        rt = self.middle(root.right, var)
        return var
    
    def back(self, root, var=None):
        if root is None:
            return
        if var is None:
            var = []
        lt = self.back(root.left, var)
        rt = self.back(root.right, var)
        var.append(root.val)
        return var

# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

#
# 
# @param root TreeNode类 the root of binary tree
# @return int整型二维数组
#
firstArr = []
midArr = []
lastArr = []
class Solution:
    def threeOrders(self , root ):
        # write code here
        res = []
        #前序遍历
        res.append(self.firstSearch(root))
        res.append(self.midSearch(root))
        res.append(self.lastSearch(root))
        return res

    def firstSearch(self, root):

        if root != None:
            firstArr.append(root.val)
            self.firstSearch(root.left)
            self.firstSearch(root.right)
        return firstArr

    def midSearch(self, root):
        if root != None:
            self.midSearch(root.left)
            midArr.append(root.val)
            self.midSearch(root.right)
        return midArr

    def lastSearch(self, root):

        if root != None:
            self.lastSearch(root.left)
            self.lastSearch(root.right)
            lastArr.append(root.val)
        return lastArr

https://blog.csdn.net/chinesekobe/article/details/110874773?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164333012316780261931344%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=164333012316780261931344&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2alltop_positive~default-1-110874773.first_rank_v2_pc_rank_v29&utm_term=%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E9%81%8D%E5%8E%86&spm=1018.2226.3001.4187
在这里插入图片描述

# -*- coding:utf-8 -*-
class Solution:
    def GetLeastNumbers_Solution(self, tinput, k):
        # write code here
        l = len(tinput)
        for i in range(k):
            # find the smallest number
            min_index = i
            for j in range(i+1, l):
                if tinput[j]< tinput[min_index]:
                    min_index = j
            tinput[i], tinput[min_index] = tinput[min_index], tinput[i]

        return tinput[0:k]

方法一:排序
本题使用排序算法解决最直观,对数组 arr 执行排序,再返回前 kk 个元素即可。使用任意排序算法皆可,本文采用并介绍 快速排序 ,为下文 方法二 做铺垫。
快速排序原理:
快速排序算法有两个核心点,分别为 “哨兵划分” 和 “递归” 。
哨兵划分操作: 以数组某个元素(一般选取首元素)为 基准数 ,将所有小于基准数的元素移动至其左边,大于基准数的元素移动至其右边。
如下图所示,为哨兵划分操作流程。通过一轮 哨兵划分 ,可将数组排序问题拆分为 两个较短数组的排序问题 (本文称之为左(右)子数组)

kua
class Solution:
    def GetLeastNumbers_Solution(self, tinput, k):
        # write code here
        def quick_sort(arr, l, r):
            if l>=r: return
            i, j = l, r 
            while i < j:
                while i < j and tinput[j] >= tinput[l]: j-=1
                while i < j and tinput[i] <= tinput[l]: i+=1
                tinput[i], tinput[j] = tinput[j], tinput[i]
            tinput[i], tinput[l] = tinput[l], tinput[i]
            quick_sort(tinput, l, i-1)
            quick_sort(tinput, i+1, r)
        quick_sort(tinput, 0, len(tinput)-1)
        return tinput[:k]

在这里插入图片描述

# -*- coding:utf-8 -*-
class Solution:
    def jumpFloor(self, number):
        # write code here
        #由于一次可以跳1个台阶或2个台阶,所以可得到
        if number < 3:
            return number
        #当台阶大于等于3的时候,f(n) = f(n - 1) + f(n - 2)
        return self.jumpFloor(number - 1) + self.jumpFloor(number - 2)
# -*- coding:utf-8 -*-
class Solution:
    def jumpFloor(self, number):
        # write code here
        #由于一次可以跳1个台阶或2个台阶,所以可得到
        if number < 3:
            return number
        #当台阶大于等于3的时候
        else:
            #定义初始值为1 和 2
            a, b =1, 2
            for i in range(number - 2): 
                a, b = b, a + b     #根据f(n) = f(n-1) + f(n-2),可得状态转移方程如左

            return b

在这里插入图片描述

# -*- coding:utf-8 -*-
class Solution:
    def FindGreatestSumOfSubArray(self, array):
        # write code here
        dp = [i for i in array]
        for i in range(1,len(array)):
            dp[i] = max(dp[i-1]+array[i],array[i])
        return max(dp)

最长无重复字数组
在这里插入图片描述
队列的思想,队列和堆栈的不同是:先进先出,所以要用pop(0)来剔除首元素

class Solution:
    def maxLength(self , arr ):
        # write code here
        res = 0
        l = list()
        for i in arr:
            while i in l:
                l.pop(0)
            l.append(i)
            res = max(res, len(l))
        return res
class Solution:
    def maxLength(self , arr ):
        # write code here
        l = []
        m = 0
        n = 0
        for i in arr:
            if i not in l:
                l.append(i)
                n += 1
            else:
                m = max(m,n)
                l = l[l.index(i)+1:]
                l.append(i)
                n = len(l)
        return max(m,n)

在这里插入图片描述
使用小学时候的方法

#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
# 计算两个数之和
# @param s string字符串 表示第一个整数
# @param t string字符串 表示第二个整数
# @return string字符串
#
class Solution:
    def solve(self , s , t ):
        # write code here
        full = 0 #保存进位
        l1,l2 = len(s),len(t)
        length_max = max(l1,l2)
        result = ''
        for i in range(length_max):
            if i<l1:
                x1 = int(s[l1-i-1])
            else:
                x1 = 0
            if i<l2:
                x2 = int(t[l2-i-1])
            else:
                x2 = 0
            tem = x1+x2+full
            if tem >=10: #判断进位
                full =1
                result += (str(tem-10))
            else:
                full = 0 
                result += (str(tem))
        if full == 1: #判断首位是否进位
            result += '1'
        return result[::-1]

在这里插入图片描述

#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 反转字符串
# @param str string字符串 
# @return string字符串
#
class Solution:
    def solve(self , str: str) -> str:
        # write code here
        if not str:
            return ""
        nums = list(str)
        i = 0
        j = len(nums)-1
        while i < j:
            nums[i], nums[j] = nums[j], nums[i]
            i += 1
            j -= 1
        return ''.join(nums)
#         return str[::-1]  # 一行解决字符串反转,没有额外空间

class Solution:
    def solve(self , str: str) -> str:
        new_str = ""
        for i in str:
            new_str = i + new_str
        return new_str
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值