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
     
  • 相关阅读:
    C#构造函数、操作符重载以及自定义类型转换
    类型和成员基础
    基元类型、引用类型和值类型
    类型基础
    Sublime之快捷键(二)
    Sublime之插件的安装(三)
    Sublime删除项目删不掉?
    Sublime之插件的安装(二)
    手机网页的头部meta的相关配置~~
    Rem自适应js---flexible.min.js
  • 原文地址:https://www.cnblogs.com/tfknight/p/12791211.html
Copyright © 2011-2022 走看看