zoukankan      html  css  js  c++  java
  • leetcode刷题

    python刷题常用数据结构

    引用自:https://blog.csdn.net/afterlake/article/details/100054150

    我总结了一下自己在刷leetcode时关于python这个语言的经常被使用的数据结构和内置方法。

    基础
    离开数据结构,算法就是空中楼阁,所以了解python内置的数据类型用法和其效率是非常有必要的

    list
    list作为最常见的内置数据结构,其不仅可以当作C语言的数组来使用,一些python特有的特性往往可以事半功倍

    append  在list的结尾追加一个元素

    sort  对list进行排序,在list长度小的时候使用插入排序,在长度大的时候使用快排,所以其时间复杂度可以视为O(nlgn)

    pop  将最后一个元素重list内部弹出并返回

    切片  python强大的语法糖之一,不仅可以用非负数索引,负数索引的合理使用可以节省不少代码量

    set
    set本质是哈希表,会对其内部元素去重,检查一个元素是否在set内部的时间复杂度是O(1)

    常用的方法为

    add  添加一个元素,就算是用一个元素多次添加,其内部也仅保留一份

    pop  随机弹出一个元素并返回

    dict
    同set一样,dict本质也是哈希表,但是set是单个元素,dict是key-value的组合

    setdefault  接受两个入参key、default, 如果dict存在key则不做任何操作,如果不存在key,则创建一个 key其value为default

    get  同setdefault一样接受两个参数key、default,如果存在key,则返回其value,否则返回default

    pop 同setdefault一样接受两个参数key、default,如果存在key,则删除key返回其value,否则返回default

    str
    字符串也是一个经常在算法中常用的数据结构,在python中str是不可变对象,支持”+“操作当时效率不高需要慎用

    split  用指定的分隔符将str分割为list

    strip 返回str去掉首尾的空白符后新的str,原来的str不受影响

    join 用str作为连接符连接参数里面的每一个元素,常常用来替代”+“

    进阶
    这里介绍几个常用的内置函数

    int 将一个参数转为int类型,在遇到字母等字符时会抛出错误

    sum 返回参数的求和

    min 返回多个参数的最小值

    max 返回多个参数的最大值

    abs 返回一个数字的绝对值

    高级
    这里对于数据结构的知识点要求就比较高了,仅仅介绍常用方法,如果不了解其特性的还请自己查阅资料

    queue 队列
    put 入队操作

    get 出队操作

    list 栈
    这里又有list,是因为python没有单独的栈,在需要栈的时候往往使用list

    append 入栈

    pop 出栈

    heapq 堆
    仅支持最小堆,有个小技巧:如果最大堆,取反之后再放入堆,取出的时候再取反

    heapfiy  将一个list转为最小堆

    heappush  往一个最小堆添加元素

    heappop  弹出堆中的最小值并返回

    题目:

    给定 matrix =
    [
    [1,2,3],
    [4,5,6],
    [7,8,9]
    ],

    原地旋转输入矩阵,使其变为:
    [
    [7,4,1],
    [8,5,2],
    [9,6,3]
    ]

    class Solution(object):
        def rotate(self, matrix):
            """
            :type matrix: List[List[int]]
            :rtype: None Do not return anything, modify matrix in-place instead.
            """
            length=len(matrix)
            ans=[]
            for i in range(length):
                row=[]
                for j in range(length):
                    row.append(matrix[length-j-1][i])
                ans.append(row)
            matrix[:]=ans
            return matrix
    View Code

    字符串轮转。

    给定两个字符串s1和s2,请编写代码检查s2是否为s1旋转而成(比如,waterbottle是erbottlewat旋转后的字符串)。

    示例1:

    输入:s1 = "waterbottle", s2 = "erbottlewat"
    输出:True

    return len(s1) == len(s2) and s1 in s2*2
    

      

    链表去重

    编写代码,移除未排序链表中的重复节点。保留最开始出现的节点。

    示例1:

     输入:[1, 2, 3, 3, 2, 1]
     输出:[1, 2, 3]
    # Definition for singly-linked list.
    # class ListNode(object):
    #     def __init__(self, x):
    #         self.val = x
    #         self.next = None
    
    class Solution(object):
        def removeDuplicateNodes(self, head):
            """
            :type head: ListNode
            :rtype: ListNode
            """
            if not head:
                return head
            history = set()
            # history = []
            temp = head
            while temp:
                if temp.val not in history:
                    # history.append(temp.val)
                    history.add(temp.val)
                    pre = temp
                    temp = temp.next
                else:
                    pre.next = temp.next
                    temp = temp.next
    
            return head
    View Code

    输出链表的倒数k个元素

    暴力破解

    class Solution(object):
        def kthToLast(self, head, k):
            """
            :type head: ListNode
            :type k: int
            :rtype: int
            """
            cur = head
            n = 0
            while cur.next:
                n += 1
                cur = cur.next
            c,cur2 = 0,head
            while c <= n-k:
                c += 1
                cur2 = cur2.next
            return cur2.val
    View Code

    机器人过关问题

    输入:
    [
      [0,0,0],
      [0,1,0],
      [0,0,0]
    ]
    输出: [[0,0],[0,1],[0,2],[1,2],[2,2]]
    解释:
    输入中标粗的位置即为输出表示的路径,即
    0行0列(左上角) -> 0行1列 -> 0行2列 -> 1行2列 -> 2行2列(右下角)

    思路:递归,注意边界条件

    # 递归算法
    class Solution:
        def move(self, path, now, grid, r, c):                  # 传入递归变量path(保存正确路径),现在的位置,整个地图,以及地图大小(重复传入避免重复计算)
            print(now)
            if now==[r-1, c-1]:                                     # 递归终止条件: 现在在终点
                path.insert(0, now)                                     # 把当前位置(终点)插入正确路径的首位(因为它是第一个完成的所以插在首位,后面的位置都插在他前面)
                return True, now
            else:                                                   # 递归: 若不在终点
                if now[1]<=c-2 and grid[now[0]][now[1]+1]==0:           # 若当前位置的右边可行进(注意与可完成的区别),则
                    next_op = [now[0], now[1]+1]                            # 下一步向右
                    now_way = self.move(path, next_op, grid, r, c)          # 接受向右的结果
                    if now_way[0]:                                              # 向右可到达(则当前位置可到达)
                        path.insert(0, now)                                     # 把当前位置插在历史记录的可到达路径的首位
                        return True, path
                    elif now[0]<=r-2 and grid[now[0]+1][now[1]]==0:     # 若右方不可行进
                        next_op = [now[0]+1, now[1]]                        # 则尝试下方
                        now_way = self.move(path, next_op, grid, r, c)      # 接受向下的结果
                        if now_way[0]:                                          # 向下可到达(则当前位置可到达)
                            path.insert(0, now)                                 # 把当前位置插在历史记录的可到达路径的首位
                            return True, path
                        else:                                           # 若右方与下方均不可到达
                            return False,                                   # 则当前位置不可到达终点
                    else:
                        return False, 
                elif now[0]<=r-2 and grid[now[0]+1][now[1]]==0:         # 若右方不可行进(如有障碍物或者到地图边缘)
                    next_op = [now[0]+1, now[1]]                            # 下一步向下
                    now_way = self.move(path, next_op, grid, r, c)
                    if now_way[0]:
                        path.insert(0, now)
                        return True, path
                    else:
                        return False, 
                else:                                                   # 若右方与下方均不可行进
                    return False,                                           # 则当前位置不可到达
    
        def pathWithObstacles(self, obstacleGrid: List[List[int]]) -> List[List[int]]:
            r = len(obstacleGrid)
            c = len(obstacleGrid[0]) # 记录下地图的大小
            if r==1 and c==1:   # 如果是1x1直接返回结果
                if obstacleGrid[0][0]==0:
                    return [[0, 0]]
                else:
                    return []
            if obstacleGrid[0][0]==1 or obstacleGrid[r-1][c-1]==1: # 如果起点或者终点有障碍物则判否
                return []
            way = self.move([], [0, 0], obstacleGrid, r, c) # 递归运算,返回值是元组,way[0]表示是否存在路径,way[1]给出路径
            print(way)
            if way[0]:
                return way[1]
            else:
                return []
    View Code

    思路: 递归,从根开始

    # Definition for a binary tree node.
    # class TreeNode(object):
    #     def __init__(self, x):
    #         self.val = x
    #         self.left = None
    #         self.right = None
    
    class Solution(object):
        def pathSum(self, root, sum):
            """
            :type root: TreeNode
            :type sum: int
            :rtype: int
            """
            self.ans = 0
            def f(node, vals):
                if node:
                    vs = [i + node.val for i in vals] + [node.val]
                    for i in range(len(vs)):
                        if vs[i] == sum:
                            self.ans += 1
                    f(node.left, vs)
                    f(node.right, vs)
            f(root, [])
            return self.ans
    View Code

    照样普通二分可以做

     两个等价
    mid = (left + right) >> 1
    mid = (left + right) /2


    把循环的归类

    编写一种方法,对字符串数组进行排序,将所有变位词组合在一起。变位词是指字母相同,但排列不同的字符串。

    对于这种去重、分类问题,用sorted()排序之后就可以放入dict了

    括号匹配问题:

    括号。设计一种算法,打印n对括号的所有合法的(例如,开闭一一对应)组合。

    说明:解集不能包含重复的子集。

    例如,给出 n = 3,生成结果为:

    [
    "((()))",
    "(()())",
    "(())()",
    "()(())",
    "()()()"
    ]

    class Solution(object):
        def generateParenthesis(self, n):
            """
            :type n: int
            :rtype: List[str]
            """
            re = []
            state = ''
            def dsp(state, p, q):       #p,q分别表示(和)还剩的个数,有个隐含条件:就是(在组合时候比)用的多或相等
                if p > q:               #非法,剪枝
                    return 
                if q == 0:              #)用完之时
                    re.append(state)
                
                if p > 0:
                    dsp(state+'(', p-1, q)
                if q > 0:
                    dsp(state+')', p, q-1)
    
            dsp(state, n, n)
            return re
    View Code
     
  • 相关阅读:
    SQLMAP注入教程-11种常见SQLMAP使用方法详解
    VS2012/2013/2015/Visual Studio 2017 关闭单击文件进行预览的功能
    解决 IIS 反向代理ARR URLREWRITE 设置后,不能跨域跳转 return Redirect 问题
    Spring Data JPA one to one 共享主键关联
    JHipster 问题集中
    Spring Data JPA 定义超类
    Spring Data JPA查询关联数据
    maven命名
    maven仓库
    Jackson读取列表
  • 原文地址:https://www.cnblogs.com/tfknight/p/12791211.html
Copyright © 2011-2022 走看看