IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> Leetcode刷题小汇总 -> 正文阅读

[数据结构与算法]Leetcode刷题小汇总

消除重复项,合并区间:

例如:

输入:intervals = [[1,3],[2,6],[8,10],[15,18]]
输出:[[1,6],[8,10],[15,18]]
解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
?
class Solution(object):
 ? ?def merge(self, intervals):
 ? ? ? ?intervals.sort() ?#对输入的列表进行排序
 ? ? ? ?he = [intervals[0]] ? ?#保存第一个数组并生成列表
 ? ? ? ?for i in intervals[1:]: ? ?
 ? ? ? ? ? ?if he[-1][1] >= i[0]: ? #如果新列表中最后一个数组的第2位大于后一个数组的第1位,将新列表中的进行替换
 ? ? ? ? ? ? ? ? he[-1][1] = max(i[1], he[-1][1]) ?
 ? ? ? ? ? ?else:
 ? ? ? ? ? ? ? ?he.append(i) ? ?#否则,直接无条件的添加
 ? ? ? ?return he

思路:合并是前一个数组的第二个数据大于第后一个数组的第一个数据,判断是否大于,大于的话进行合并并插入新的数组中,否则,直接进行插入。新数组首先存入第一个数组为参照,然后每次判断取最后一个数组进行比较。

python的数组的水平翻转:

intervals[::] = intervals[::-1]

python的逆时针翻转90:

给你一幅由 N × N 矩阵表示的图像,其中每个像素的大小为 4 字节。请你设计一种算法,将图像旋转 90 度。

for i in range(len(matrix)):
 ? ? ? ? ? ?for m in range(i):
 ? ? ? ? ? ? ? ?matrix[i][m],matrix[m][i] = matrix[m][i],matrix[i][m] ? #对角线翻转
 ? ? ? ?
 ? ? ? ?for h in range(len(matrix)):
 ? ? ? ? ? ?matrix[h][::] = matrix[h][::-1]

逆时针翻转,对角线翻转,在水平翻转就是逆时针翻转的效果。

最长的公共前缀:

示例 1:

输入:strs = ["flower","flow","flight"]
输出:"fl"
class Solution(object):
 ? ?def longestCommonPrefix(self, strs):
 ? ? ? ?if len(strs) == 0: ? ?#如果为空字符串,则返回''
 ? ? ? ? ? ? ? ? ? ?return ''
 ? ? ? ?res = '' ? ?#用于存放
 ? ? ? ?for i in range(len(strs[0])): ? #以第一个字符串的大小为循环的参照
 ? ? ? ? ? ?for str in strs: ? ? ? ? ? #遍历列表中的每一个字符串
 ? ? ? ? ? ? ? ?if len(str) <= i: ? ? ? #如果小于i,当前的个数, <=,因为是从0开始的,数字从1开始的
 ? ? ? ? ? ? ? ? ? ?return res ? ? ? ? ? ? ? # ? ? ? ? ? ? ? ? ?  所以有等于号(特别注意)
 ? ? ? ? ? ? ? ?else:
 ? ? ? ? ? ? ? ? ? ?if str[i] != strs[0][i]: ? ?#或者字符串中的第i位与第一个字符串中的第i位不相等
 ? ? ? ? ? ? ? ? ? ? ? ?return res ? ? ? ? ? ? ? #直接返回
 ? ? ? ? ? ?res += strs[0][i] ? ? ? #遍历strs,处理不在其他中或其他字符串过短的问题,
 ? ? ? ?return res

直接取得第一个数据为参照,以它长度进行循环,如果有字符串小于当前的i,那么最长公共前缀不可能更大,直接放回,否则,判断当前字符串是否相等,不相等就直接返回,否则就存入res中并继续进行遍历。

中心元素的下标:

 ?all = sum(nums) ? #求和
 ? ? ? ?t = 0
 ? ? ? ?for i in range(len(nums)): ?
 ? ? ? ? ? ?if t * 2 + nums[i] == all: ? #判断左边的2倍加上中间的数是否等于sum,如果不存在,就查找失败
 ? ? ? ? ? ? ? ?return i 
 ? ? ? ? ? ?else:
 ? ? ? ? ? ? ? ?t += nums[i] ? ?#前i项和存入t中
?
 ? ? ? ?return -1

中心元素就是两边的数加起来等于0,那么中心元素的左半边的2倍在加上中心元素应该等于总和。

零矩阵 编写一种算法,若M × N矩阵中某个元素为0,则将其所在的行与列清零。

示例 1:

输入: [ [1,1,1], [1,0,1], [1,1,1] ] 输出: [ [1,0,1], [0,0,0], [1,0,1] ]

class Solution(object):
 ? ?def setZeroes(self, matrix):
 ? ? ? ?x_zero = []
 ? ? ? ?y_zero = []
 ? ? ? ?l = len(matrix)
 ? ? ? ?s = len(matrix[0])
 ? ? ? ?for i in range(l):
 ? ? ? ? ? ?for m in range(s):
 ? ? ? ? ? ? ? ?if matrix[i][m] == 0:
 ? ? ? ? ? ? ? ? ? ?x_zero.append(i)
 ? ? ? ? ? ? ? ? ? ?y_zero.append(m)
 ? ? ? ?for i in range(l):
 ? ? ? ? ? ?if i in x_zero:
 ? ? ? ? ? ? ? ?for d in range(s):
 ? ? ? ? ? ? ? ? ? ?matrix[i][d] = 0
?
 ? ? ? ?for i in range(s):
 ? ? ? ? ? ?if i in y_zero:
 ? ? ? ? ? ? ? ?for e in range(l):
 ? ? ? ? ? ? ? ? ? ?matrix[e][i] = 0

通过循环找出为0的数据并保存其x,y坐标,然后再将x,y的那一横,纵分别全部变成0,

给你一个字符串 s,找到 s 中最长的回文子串。

示例 1:

输入:s = "babad" 输出:"bab" 解释:"aba" 同样是符合题意的答案。

class Solution:
 ? ?def longestPalindrome(self, s: str) -> str:
 ? ? ? ?"""
 ? ? ?  回文串:正读和反读都一样的字符串(可以理解为对称的字符串)
 ? ? ?  思路: 1 分为奇数串('aba')和偶数串(’abba‘)两种情况
 ? ? ? ? ? ? 2 把每个字符当做回文串中间的字符,由内向外延展比较
 ? ? ? ? ? ? ?  (定义由内向外的两个索引值)
 ? ? ?  """
 ? ? ? ?res = ""
 ? ? ? ?for i in range(len(s)):
 ? ? ? ? ? ?# 奇数情况
 ? ? ? ? ? ?tmp = self.helper(s, i, i)
 ? ? ? ? ? ?if len(tmp) > len(res):
 ? ? ? ? ? ? ? ?res = tmp ? ? ? ? ? ? ?#res不断的进行迭代,将最长的字符串保存到res里面
 ? ? ? ? ? ?# 偶数情况
 ? ? ? ? ? ?tmp = self.helper(s, i, i+1)
 ? ? ? ? ? ?if len(tmp) > len(res):
 ? ? ? ? ? ? ? ?res = tmp
 ? ? ? ?return res
 ? ?
 ? ?def helper(self, s, l, r): ? ?
 ? ? ? ?while l >=0 and r < len(s) and s[l]==s[r]:
 ? ? ? ? ? ?l -= 1; r += 1
 ? ? ? ?return s[l+1:r]
?

给你一个字符串 s ,颠倒字符串中 单词 的顺序。

示例 2:

输入:s = "  hello world  "
输出:"world hello"
解释:颠倒后的字符串中不能存在前导空格和尾随空格。
class Solution(object):
 ? ?def reverseWords(self, s):
 ? ? ? ?s1 = ' '.join(s.split()[::-1])
 ? ? ? ?return s1

' '.join(),可以去除多于的空格,split()[::-1],加上前面的就是以空格数据依据,进行倒叙

最大字数组和:

输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。
class Solution(object):
 ? ?def maxSubArray(self, nums):
 ? ? ? ?size = len(nums)
 ? ? ? ?if size == 0:
 ? ? ? ? ? ?print(0)
 ? ? ? ?dp = [0 for _ in range(size)] ? ?#创建一个长度为len的数组
?
 ? ? ? ?dp[0] = nums[0] ? ?#将第一个数据赋值给第一个
 ? ? ? ?for i in range(1, size):
 ? ? ? ? ? ?if dp[i - 1] >= 0: ? ? #如果前面的数据和大于0,就加起来存进去
 ? ? ? ? ? ? ? ?dp[i] = dp[i - 1] + nums[i]
 ? ? ? ? ? ?else:
 ? ? ? ? ? ? ? ?dp[i] = nums[i] ? ?#否则直接存进去
 ? ? ? ?return max(dp)

思路:累计最大,以前面为标准,如果前面的和为负数,会拉小数据,不加进去,直接保存当前 i 的数据,大于0则将数据加进去,最后求最大

反转字符串:

示例 1:

输入:s = ["h","e","l","l","o"]
输出:["o","l","l","e","h"]
class Solution(object):
 ? ?def reverseString(self, s):
 ? ? ? ?"""
 ? ? ?  :type s: List[str]
 ? ? ?  :rtype: None Do not return anything, modify s in-place instead.
 ? ? ?  """
 ? ? ? ?m,n = 0, len(s)-1
 ? ? ? ?while m<n:
 ? ? ? ? ? ?s[m], s[n] = s[n],s[m]
 ? ? ? ? ? ?m += 1; n -= 1
 ? ? ? ?return s

day2:

数组拆分 I

示例 1:

输入:nums = [1,4,3,2] 输出:4 解释:所有可能的分法(忽略元素顺序)为:

  1. (1, 4), (2, 3) -> min(1, 4) + min(2, 3) = 1 + 2 = 3

  2. (1, 3), (2, 4) -> min(1, 3) + min(2, 4) = 1 + 2 = 3

  3. (1, 2), (3, 4) -> min(1, 2) + min(3, 4) = 1 + 3 = 4 所以最大总和为 4

思路:两两拆分,返回最小,实际上就是将排序之后的偶数项相加:

class Solution(object):
 ? ?def arrayPairSum(self, nums):
 ? ? ? ?"""
 ? ? ?  :type nums: List[int]
 ? ? ?  :rtype: int
 ? ? ?  """
 ? ? ? ?l = len(nums) ? ?#法1
 ? ? ? ?nums.sort()
 ? ? ? ?res = 0
 ? ? ? ?for i in range(l):
 ? ? ? ? ? ?if i%2 == 0:
 ? ? ? ? ? ? ? ?res += nums[i]
 ? ? ? ?return res
 ? ?
 ? ?return sum(sorted(nums)[::2]) ?#法2,原理差不多
 ? ?

两数之和 II - 输入有序数组

示例 1:

输入:numbers = [2,7,11,15], target = 9 输出:[1,2] 解释:2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。返回 [1, 2] 。

思路:采用二分法,从两端的和开始判断,如果小于目标值,左边的向右移动,反之右边的向左边移

class Solution(object):
 ? ?def twoSum(self, numbers, target):
 ? ? ? ?l = len(numbers)
 ? ? ? ?l2 = l//2
 ? ? ? ?for i in range(l):
 ? ? ? ? ? ?for m in range(l):
 ? ? ? ? ? ? ? ?if numbers[i]+ numbers[m] == target and i != m:
 ? ? ? ? ? ? ? ? ? ?return [i+1,m+1] ? ?#暴力法,超时了。。。
 ?#优化 
class Solution(object):
 ? ?def twoSum(self, numbers, target):
 ? ? ? ?m = len(numbers)-1
 ? ? ? ?i = 0 
 ? ? ? ?while i< m: ? #i一定在m的左边
 ? ? ? ? ? ? ? ?if numbers[i]+numbers[m] < target:
 ? ? ? ? ? ? ? ? ? ?i += 1
 ? ? ? ? ? ? ? ?elif numbers[i]+numbers[m] > target:
 ? ? ? ? ? ? ? ? ? ?m -=1
 ? ? ? ? ? ? ? ?else:
 ? ? ? ? ? ? ? ? ? ?return [i+1,m+1]
 ? ? ? ?return -1
?

移除元素

示例 1:

输入:nums = [3,2,2,3], val = 3 输出:2, nums = [2,2] 解释:函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。例如,函数返回的新长度为 2 ,而 nums = [2,2,3,3] 或 nums = [2,2,0,0],也会被视作正确答案。

思路:主要是使用双指针,快指针和慢指针,当块指针不等于val的时候,将该数赋值给慢指针,也就是说快指针用于查找不等于val的数并将它赋值给慢指针,最后返回慢指针即达到移除元素:

class Solution(object):
    def removeElement(self, nums, val):
        """
        :type nums: List[int]
        :type val: int
        :rtype: int
        """
        l = len(nums)
        m = 0
        for i in range(l):
            if nums[i] != val:     #当快指针找到不等于val的数
                nums[m]= nums[i]    #将它赋值给慢指针m ,m并向后移动以便接下来进行下一个数的存储
                m += 1
        return m

最大连续1的个数

示例 1:

输入:nums = [1,1,0,1,1,1] 输出:3 解释:开头的两位和最后的三位都是连续 1 ,所以最大连续 1 的个数是 3.

思路:遍历nums,将1的个数存下来,并对保存下来的个数进行比较,返回最大值。

class Solution(object):
    def findMaxConsecutiveOnes(self, nums):
        res = 0
        count = 0
        l = len(nums)
        for i in range(l):
            if nums[i] == 1:
                count +=1     # count用于计数1出现的个数
            else:
                count = 0     # 当出现非1,则将count清零
            res = max(count,res)  #对count的计数和res取最大值
        return res

长度最小的子数组

示例 1:

找出该数组中满足其和 ≥ target 的长度最小的 连续子数组

输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。

思路:主要使用双指针滑动窗口,快的滑动,当数据大于目标值,则慢的哪一个向右滑动,并获得计算数组的长度

class Solution(object):
    def minSubArrayLen(self, target, nums):
        """
        :type target: int
        :type nums: List[int]
        :rtype: int
        """
       
        l = len(nums)
        left = 0
        total = 0     # 用于存放总数
        right = 0
        count = len(nums)+1     
        while right <= l-1:     #右边的快的一个不能大于边界len()-1
            total += nums[right]      # Total 计算left到right之间的距离
            while total>= target:      # 总数大于目标值了,left向右移动
                count = min(right-left+1, count)   # 比较查找最小值
                total -= nums[left]           #减去left滑动的那个数值
                left += 1
            right += 1
        return (0 if count==len(nums)+1 else count)

杨辉三角

给定一个非负整数 numRows生成「杨辉三角」的前 numRows 行。

示例 1:

输入: numRows = 5
输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]

思路:输出的每一项个列表的个数逐个增多,用循环创建一个结构相似的表,在从第三行开始修改,该m位置上的数字等于上一行的m位置+m-1的位置的。

class Solution(object):
    def generate(self, numRows):
        """
        :type numRows: int
        :rtype: List[List[int]]
        """
        list = [[1]*i for i in range(1,numRows+1)]  # 创建基本的表结构
        for i in range(2,numRows):    # 从第3行开始遍历
            for m in range(1,i):
                list[i][m] = list[i-1][m] + list[i-1][m-1]  # 数据等于上一个两个数据相加
        return list

杨辉三角 II

给定一个非负索引 rowIndex,返回「杨辉三角」的第 rowIndex 行。

示例 1:

输入: rowIndex = 3
输出: [1,3,3,1]

思路与上面类似,多加一个为0,1的判断即可

class Solution(object):
 ? ?def getRow(self, rowIndex):
 ? ? ? ?list = [[1]*i for i in range(1, rowIndex+2)] ? #防止输入0,1,进行了rowIndex+2
 ? ? ? ?if rowIndex <= 1: ? ? ? ? ? ?# 为0,1时,都是1,可以直接返回
 ? ? ? ? ? ?return list[rowIndex]
 ? ? ? ?else:
 ? ? ? ? ? ?for i in range(2,rowIndex+1): ? ?#思路和上面类似
 ? ? ? ? ? ? ? ?for m in range(1,i):
 ? ? ? ? ? ? ? ? ? ?list[i][m] = list[i-1][m-1]+list[i-1][m]
 ? ? ? ? ? ?return list[rowIndex]

反转字符串中的单词 III

示例 1:

输入:s = "Let's take LeetCode contest"
输出:"s'teL ekat edoCteeL tsetnoc"
class Solution(object):
 ? ?def reverseWords(self, s):
 ? ? ? ?return ?' '.join(word[::-1] for word in s.split())

s.split()转换为列表,进行遍历,对每一个单词单独进行反转,最后转成字符串在返回

删除排序数组中的重复项

给你一个 升序排列 的数组 nums ,请你?原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致

示例 1:

输入:nums = [1,1,2] 输出:2, nums = [1,2,_] 解释:函数应该返回新的长度 2 ,并且原数组 nums 的前两个元素被修改为 1, 2 。不需要考虑数组中超出新长度后面的元素。

思路:和删除某个数字思路一样,使用双指针,一个快指针,一个慢指针,当快指针找到不等于慢指针的数(以为数组本来就是升序)则让慢指针向前+1,并把不一样的数字赋值给慢指针

class Solution(object):
    def removeDuplicates(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
     
        l = len(nums)
        m = 0
        for i in range(l):
            if nums[i] != nums[m]:
                m += 1
                nums[m]= nums[i]
        return m+1 

对角线遍历

示例 1:

输入:mat = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,4,7,5,3,6,8,9]

思路:将矩阵的坐标写出来,由图可以发现,下标加起来为偶数的在一起,下标加起来为奇数的在一起,创建一个数组嵌套5个数组分别存放,在一横排中,下标为奇数的却应该在该坐标的最后一个,偶数的在数组的第一个,于是。。。

class Solution(object):
 ? ?def findDiagonalOrder(self, mat):
 ? ? ? ?"""
 ? ? ?  :type mat: List[List[int]]
 ? ? ?  :rtype: List[int]
 ? ? ?  """
 ? ? ? ?l = len(mat)
 ? ? ? ?l1 = len(mat[0])
 ? ? ? ?res = [[] for _ in range(l + l1 - 1)] ?# 建立一个对角线个数的数组用于存放
 ? ? ? ?result = []
 ? ? ? ?for i in range(l):
 ? ? ? ? ? ?for m in range(l1): ? ? ?# 遍历数组
 ? ? ? ? ? ? ? ?if (i + m) % 2 != 0: ? ? # 为奇数的时候,直接添加到对应(i+m)的数组
 ? ? ? ? ? ? ? ? ? ?res[i + m].append(mat[i][m])
 ? ? ? ? ? ? ? ?else:
 ? ? ? ? ? ? ? ? ? ?res[i + m].insert(0, mat[i][m]) ?# 下标为偶数的时候,最先遍历到的应该在最后,所以把后加进来的insert到该数组的第一位
 ? ? ? ?for i in res:
 ? ? ? ? ? ?result += i ? ?# 遍历该数组加到一个新的数组
 ? ? ? ?return result

无重复字符的最长子串:

给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。

示例 1:

输入: s = "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

思路:使用滑动窗口的办法,遍历字符串,在发现相同的字符之后,那么剔除相同字符串以及之前的字符串,求长度的最大值

class Solution(object):
 ? ?def lengthOfLongestSubstring(self, s):
 ? ? ? ?a = [] ? ? # 用于临时存放暂未重复的字符
 ? ? ? ?count = 0 ? # 用于计数a的最长
 ? ? ? ?for i in s:
 ? ? ? ? ? ?if i in a:
 ? ? ? ? ? ? ? ?a = a[a.index(i) + 1:] # 当发现重复字符串,将该字符串以及之前的字符串剔除
 ? ? ? ? ? ?a.append(i)
 ? ? ? ? ? ?count = max(len(a), count)
 ? ? ? ?return count
 ? ? ? ?

盛最多水的容器

给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。

找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

示例 1:

输入:[1,8,6,2,5,4,8,3,7] 输出:49 解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。

思路:当然,看到题最先想到的是暴力法,O(n2),超时了...

优化之后的思路:主要是使用双指针,盛最多水的容器=min(l,r)*两点距离,两个指针指向两端,然后将小的哪一个向内进行移动,用一个total接收结果,并取得最大值 ,时间复杂度为O(n)

# 暴力法,超时了...
class Solution(object):
 ? ?def maxArea(self, height):
 ? ? ? ?"""
 ? ? ?  :type height: List[int]
 ? ? ?  :rtype: int
 ? ? ?  """
 ? ? ? ?total = 0
 ? ? ? ?for i in range(len(height)):
 ? ? ? ? ? ?for m in range(len(height)):
 ? ? ? ? ? ? ? ?if i != m:
 ? ? ? ? ? ? ? ? ? ?lowwer = min(height[i], height[m])
 ? ? ? ? ? ? ? ? ? ?total = max(total, lowwer * (m - i))
 ? ? ? ?return total
class Solution(object):
 ? ?def maxArea(self, height):
 ? ? ? ?total = 0
 ? ? ? ?left = 0 ? 
 ? ? ? ?right = len(height) - 1
 ? ? ? ?while left < right: ? ?# 两端移动,荟聚与中间,所以right要大于Left
 ? ? ? ? ? ?s1 = min(height[left], height[right]) * (right - left)
 ? ? ? ? ? ?total = max(total, s1)
 ? ? ? ? ? ?if height[left] > height[right]: ?#left的数据大于right,移动right
 ? ? ? ? ? ? ? ?right -= 1
 ? ? ? ? ? ?else:
 ? ? ? ? ? ? ? ?left += 1 ? ?# 否则,移动left
 ? ? ? ?return total

在排序数组中查找元素的第一个和最后一个位置

给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。

示例 1:

输入:nums = [5,7,7,8,8,10], target = 8
输出:[3,4]

思路:主要是使用二分法,用target和中间的数进行比较,如果mid大于target,那么结果一定在左边,反之亦然,每一次可以将范围缩小一半。具体的思路:在left和right中,让left找到刚刚小于target的坐标,将该坐标+1返回则是左边的边界值,让right找到刚刚大于target的坐标,并将该坐标-1即是右边的边界值:

class Solution(object):
 ? ?def searchRange(self, nums, target):
 ? ? ? ?"""
 ? ? ?  :type nums: List[int]
 ? ? ?  :type target: int
 ? ? ?  :rtype: List[int]
 ? ? ?  """
 ? ? ? ?left = self.seacher(nums, target)
 ? ? ? ?right = self.seacher(nums, target+1) ?# 右边的复用了左边查找的方法,将目标值+1,即参照比
 ? ? ? ?if left < right: ? ? ? ? ? ? ? ? ? ? ?# 目标值大1的数,mid刚好就是target,而多加了1
 ? ? ? ? ? ?return [left, right - 1] ? ? # 由于返回的right多加了1,所以减去了
 ? ? ? ?else:
 ? ? ? ? ? ?return [-1, -1]
?
 ? ?def seacher(self, nums, target):
 ? ? ? ?left = 0
 ? ? ? ?right = len(nums) ? ?# 左开右闭,所以不需要-1
 ? ? ? ?while left < right:
 ? ? ? ? ? ?mid = left + (right - left) // 2 ? # 找到中间的数
 ? ? ? ? ? ?if nums[mid] < target: ? # 找到left刚好小于target的下标
 ? ? ? ? ? ? ? ?left = mid +1 ? ? ? ?# +1返回则是边界值
 ? ? ? ? ? ?else:
 ? ? ? ? ? ? ? ?right = mid 
 ? ? ? ?return left
?

三数之和

给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。

示例 1:

输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]

思路:排序+双指针法,由于不能重复,需要排除可能重复的

1、当i >0时,总结果一定大于0 ,直接break

2、当前一个数据和后一个数据相等的时候,pass,以免引起数据的重复

3、数据为空或者长度小于3的时候,直接返回

在循环的时候,也要注意双指针的排除重复项

class Solution(object):
 ? ?def threeSum(self, nums):
 ? ? ? ?lens = len(nums)
 ? ? ? ?res = []
 ? ? ? ?nums.sort()
 ? ? ? ?if not nums or lens < 3: ?#数据为空或者长度小于3的时候,直接返回
 ? ? ? ? ? ?return res
 ? ? ? ?else:
 ? ? ? ? ? ?for i in range(lens): 
 ? ? ? ? ? ? ? ?if nums[i] > 0: ? # 当i >0时,总结果一定大于0 ,直接break
 ? ? ? ? ? ? ? ? ? ?return res
 ? ? ? ? ? ? ? ?if i > 0 and nums[i] == nums[i - 1]: #跳过前一个数据和后一个数据相等的时候 
 ? ? ? ? ? ? ? ? ? ?continue
 ? ? ? ? ? ? ? ?l = i + 1
 ? ? ? ? ? ? ? ?r = lens - 1
 ? ? ? ? ? ? ? ?while l < r: ? # 双指针条件
 ? ? ? ? ? ? ? ? ? ?if nums[i] + nums[l] + nums[r] == 0: ?# 等于0直接加进列表
 ? ? ? ? ? ? ? ? ? ? ? ?res.append([nums[i], nums[l], nums[r]])
 ? ? ? ? ? ? ? ? ? ? ? ?while l<r and nums[l] == nums[l + 1]: ?# 同理,排除双指针重复项
 ? ? ? ? ? ? ? ? ? ? ? ? ? ?l += 1
 ? ? ? ? ? ? ? ? ? ? ? ?while l<r and nums[r] == nums[r - 1]:
 ? ? ? ? ? ? ? ? ? ? ? ? ? ?r -= 1
 ? ? ? ? ? ? ? ? ? ? ? ?l += 1
 ? ? ? ? ? ? ? ? ? ? ? ?r -= 1
 ? ? ? ? ? ? ? ? ? ?elif nums[i] + nums[l] + nums[r] > 0: # 当和>0,为了降低数据,r向左移
 ? ? ? ? ? ? ? ? ? ? ? ?r -= 1
 ? ? ? ? ? ? ? ? ? ?else: ? ? ? ? ? ? ? ? ? ? ? ? # 当和<0,为了增大数据,l向右移
 ? ? ? ? ? ? ? ? ? ? ? ?l += 1
 ? ? ? ?return res

电话号码的字母组合

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。

给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

示例 1:

输入:digits = "23"
输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]
class Solution(object):
 ? ?def letterCombinations(self, digits):
 ? ? ? ?"""
 ? ? ?  :type digits: str
 ? ? ?  :rtype: List[str]
 ? ? ?  """
 ? ? ? ?if digits == '':
 ? ? ? ? ? ?return []
 ? ? ? ?results = []
 ? ? ? ?my_dict = {'2': 'abc', '3': 'def', '4': 'ghi', '5': 'jkl', '6': 'mno',
 ? ? ? ? ? ? ? ? ? ?'7': 'pqrs', '8': 'tuv', '9': 'wxyz'}
 ? ? ? ?def dfs(k, result):
 ? ? ? ? ? ?if k == len(digits):
 ? ? ? ? ? ? ? ?results.append(result)
 ? ? ? ? ? ? ? ?return results
 ? ? ? ? ? ?for i in my_dict[digits[k]]:
 ? ? ? ? ? ? ? ?dfs(k+1, result+i)
 ? ? ? ?
 ? ? ? ?dfs(0, '')
 ? ? ? ?return results

比特位计数

给你一个整数 n ,对于 0 <= i <= n 中的每个 i ,计算其二进制表示中 1 的个数 ,返回一个长度为 n + 1 的数组 ans 作为答案.

示例 1:

输入:n = 2 输出:[0,1,1] 解释: 0 --> 0 1 --> 1 2 --> 10

思路:bin(),转换为二进制,然后在计算1的个数

# 最开始的复杂版
class Solution(object):
 ? ?def countBits(self, n):
 ? ? ? ?"""
 ? ? ?  :type n: int
 ? ? ?  :rtype: List[int]
 ? ? ?  """
 ? ? ? ?res = []
 ? ? ? ?total = 0
 ? ? ? ?for i in range(n+1):
 ? ? ? ? ? ?s = bin(i)[2:]
 ? ? ? ? ? ?total = 0
 ? ? ? ? ? ?for m in s:
 ? ? ? ? ? ? ? ?total += int(m)
 ? ? ? ? ? ?res.append(total)
 ? ? ? ?return res
# 简化版
class Solution(object):
 ? ?def countBits(self, n):
 ? ? ? ?return [bin(i).count('1') for i in range(n + 1)]

有效的括号

给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

左括号必须用相同类型的右括号闭合。 左括号必须以正确的顺序闭合。

示例 1:

输入:s = "()" 输出:true

思路:将符号进行替换,判断最后的结果是否为空,为空说明全是符合

class Solution(object):
 ? ?def isValid(self, s):
 ? ? ? ?while '()' in s or '{}' in s or '[]' in s:
 ? ? ? ? ? ?s = s.replace('()','')
 ? ? ? ? ? ?s = s.replace('{}','')
 ? ? ? ? ? ?s = s.replace('[]','')
 ? ? ? ?return s== ''

删除链表的倒数第 N 个结点

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点

示例 1:

输入:head = [1,2,3,4,5], n = 2 输出:[1,2,3,5]

思路:用栈的方法,将数据全部存放在栈中,然后将N+1个数据取了出来,将需要删除的前一个指针指向下一个的下一个指针,从而删除了第N个数据

class Solution(object):
 ? ?def removeNthFromEnd(self, head, n):
 ? ? ? ?a = head
 ? ? ? ?b = ListNode(0,head)
 ? ? ? ?c = b
 ? ? ? ?list1 = list()
 ? ? ? ?while c:
 ? ? ? ? ? ?list1.append(c)
 ? ? ? ? ? ?c = c.next
 ? ? ? ?for i in range(n):
 ? ? ? ? ? ?list1.pop()
 ? ? ? ?stack = list1[-1]
 ? ? ? ?stack.next = stack.next.next
 ? ? ? ?return b.next

颜色分类

给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums ,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。

我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。

必须在不使用库的sort函数的情况下解决这个问题。

示例 1:

输入:nums = [2,0,2,1,1,0] 输出:[0,0,1,1,2,2] 思路:总共3个颜色,只需要将两个颜色归位,那么剩下一个颜色就是在位置上的,可以使用单指针或者双指针的方法

单指针:

class Solution(object):
 ? ?def sortColors(self, nums):
 ? ? ? ?lens = len(nums)
 ? ? ? ?r = 0
 ? ? ? ?for i in range(lens): ? # 从头到尾进行遍历,找出为0的值
 ? ? ? ? ? ?if nums[i] == 0:
 ? ? ? ? ? ? ? ?nums[i], nums[r] = nums[r], nums[i] # 将它与r交换,r向后一个
 ? ? ? ? ? ? ? ?r += 1
 ? ? ? ?for m in range(r, lens): ?# 在上面遍历之后,前r都为0,所以遍历r以后的数据
 ? ? ? ? ? ?if nums[m] == 1: ? ?# 为1的时候将它提前,即与r交换
 ? ? ? ? ? ? ? ?nums[m], nums[r] = nums[r], nums[m]
 ? ? ? ? ? ? ? ?r += 1

双指针:两个指针在两端,分别将0和2的数据放在两端,那么中间必定为1,从而达到排列的效果

class Solution(object):
 ? ?def sortColors(self, nums):
 ? ? ? ?lens = len(nums)
 ? ? ? ?r = 0
 ? ? ? ?l = lens - 1
 ? ? ? ?n = 0
 ? ? ? ?while n <= l: ?# 两个指针相遇遍历结束的条件
 ? ? ? ? ? ?while n <= l and nums[n] == 2: ? # 当nums[n]为2的时候,将它置于最后
 ? ? ? ? ? ? ? ?nums[l], nums[n] = nums[n], nums[l]# 即与l交换
 ? ? ? ? ? ? ? ?l -= 1 ? ? ? ? ? ? ? ? ? ? ? ? ? ? # l向前移动1位
 ? ? ? ? ? ?if nums[n] == 0: ? ? # 当nums[n]为0的时候,将它置于最前
 ? ? ? ? ? ? ? ?nums[n], nums[r] = nums[r], nums[n] ?# 与r的数据进行交换
 ? ? ? ? ? ? ? ?r += 1
 ? ? ? ? ? ?n += 1 ? ?
 ? ? ? ?return nums
?

最小路径和

给定一个包含非负整数的 m x n 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。

说明:每次只能向下或者向右移动一步。

示例 1:

输入:grid = [[1,3,1],[1,5,1],[4,2,1]] 输出:7 解释:因为路径 1→3→1→1→1 的总和最小。

思路:动态规划的思想,计算出每一步所需要的代价,那么第一横排和第一列只能单向的走,代价进行简单的累加即可,剩下的数据为该位置的数据加上上面或者左侧的数据,取最小值即可,最后返回最后一个数据即可。

class Solution(object):
 ? ?def minPathSum(self, grid):
 ? ? ? ?height = len(grid)
 ? ? ? ?wide = len(grid[0])
 ? ? ? ?dp = [[0] * wide for _ in range(height)] ?# 创建一个横列和给的列表相等的列表
 ? ? ? ?dp[0][0] = grid[0][0] ? ? ? ? ? ? # 将第一个数据加到新的列表中
 ? ? ? ?if not grid or not grid[0]: ? ?
 ? ? ? ? ? ?return 0
 ? ? ? ?for i in range(1, wide): ? ? # 对第1横排数据进行替换,每一个数据代价等于前面的累加
 ? ? ? ? ? ?dp[0][i] += grid[0][i] + dp[0][i - 1]
 ? ? ? ?for m in range(1, height): ? ?# 对第1列数据进行替换,每一个数据代价等于前面的累加
 ? ? ? ? ? ?dp[m][0] += grid[m][0] + dp[m - 1][0]
?
 ? ? ? ?for i in range(1, wide): ?
 ? ? ? ? ? ?for m in range(1, height): ? # 其他数据取(上面或者左边)最小值+该位置本该有的数据
 ? ? ? ? ? ? ? ?dp[m][i] = min(dp[m][i - 1], dp[m - 1][i])+grid[m][i]
 ? ? ? ?return dp[height-1][wide-1] ? ? ? # 直接返回右下角的数据

括号生成

数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。

示例 1:

输入:n = 3 输出:["((()))","(()())","(())()","()(())","()()()"]

服了,遇到这种回溯法,递归的就做不来。。。。copy了大佬的答案

思路:递归的思想,当()的长度小于2n的时候不断的进行递归,每一次,+(或者+),直到最后长度等于2n

class Solution(object):
 ? ?def generateParenthesis(self, n):
 ? ? ? ?res = [] ? ?# 用于存放数据
?
 ? ? ? ?def func(s, left, right): ? 
 ? ? ? ? ? ?if left == right == n: ? # 返回的条件,左右括号等于n
 ? ? ? ? ? ? ? ?res.append(s)
 ? ? ? ? ? ? ? ?return
 ? ? ? ? ? ?elif right <= left <= n: ? # 当left大于right但是小于n时,一定还有符合条件的存在
 ? ? ? ? ? ? ? ?func(s + ')', left, right + 1) ?# 加)括号,左边的计数+1
 ? ? ? ? ? ? ? ?func(s + '(', left + 1, right) ? # 加(括号,右边的计数+1
?
 ? ? ? ?func('', 0, 0) ? # 传入原始的数据
 ? ? ? ?return res

最近的请求次数

写一个 RecentCounter 类来计算特定时间范围内最近的请求。

请你实现 RecentCounter 类:

RecentCounter() 初始化计数器,请求数为 0 。 int ping(int t) 在时间 t 添加一个新请求,其中 t 表示以毫秒为单位的某个时间,并返回过去 3000 毫秒内发生的所有请求数(包括新请求)。确切地说,返回在 [t-3000, t] 内发生的请求数。

思路:求的是[t-3000, t]内发生的请求数,减去t-3000,之前发生的请求数(用队列实现的)

class RecentCounter(object):
?
 ? ?def __init__(self):
 ? ? ? self.deque = deque()
?
 ? ?def ping(self, t):
 ? ? ? ?s = []
 ? ? ? 
 ? ? ? ?self.deque.append(t)
 ? ? ? ?while self.deque[0] < t-3000: ?
 ? ? ? ? ? ?self.deque.popleft() ?# 计算的是左边的
 ? ? ? ? ? ?
 ? ? ? ?return len(self.deque)

?
智能模式
?
模拟面试
?
?
?
?
?
?
1213141516171819202122231234567891011
 ? ? ? ? ?  return votes[0]
 ? ? ?  else:
 ? ? ? ? ?  for i in range(len(votes)):
 ? ? ? ? ? ? ?  for m in range(s):
 ? ? ? ? ? ? ? ? ?  keys = votes[i][m]
 ? ? ? ? ? ? ? ? ?  res[keys] += s - m
?
 ? ? ?  result = list(res.items())
 ? ? ?  # 排序
 ? ? ?  result.sort(key=lambda x: (x[1], -ord(x[0])), reverse=True)
?
?
?
?
?
?
class Solution:
 ?  def rankTeams(self, votes: List[str]) -> str:
 ? ? ?  n = len(votes[0])
 ? ? ?  # 初始化哈希映射
 ? ? ?  ranking = collections.defaultdict(lambda: [0] * n)
 ? ? ?  # 遍历统计
 ? ? ?  for vote in votes:
 ? ? ? ? ?  for i, vid in enumerate(vote):
 ? ? ? ? ? ? ?  ranking[vid][i] += 1
 ? ? ? ?
 ? ? ?  # 取出所有的键值对
 ? ? ?  result = list(ranking.items())
 ? ? ?  # 排序
 ? ? ?  result.sort(key=lambda x: (x[1], -ord(x[0])), reverse=True)
 ? ? ?  return "".join([vid for vid, rank in result])

最大公约数:

思路:约数就是能够整除,整除取余为0 ,从大到小的试,那么当两个数据取余都为0的时候就是最大的公约数

def Division(x, y):
 ? ?reduce = 0
 ? ?if x > y:
 ? ? ? ?reduce = y
 ? ?elif x < y:
 ? ? ? ?reduce = x
 ? ?else:
 ? ? ? ?return x
 ? ?while reduce > 0:
 ? ? ? ?if x % reduce == 0 and y % reduce == 0:
 ? ? ? ? ? ?return reduce
 ? ? ? ?else:
 ? ? ? ? ? ?reduce -= 1
?
?
try:
 ? ?x = int(input('请输入第一个数:'))
 ? ?y = int(input('请输入第二个数:'))
 ? ?num = Division(x, y)
 ? ?print('两个数的最大公倍数为:', num)
except:
 ? ?print('输入的格式有误!')

最大公倍数就是对于两个数据取余都为零

抢凳子游戏:

思路:一个随机数,将对应位置的淘汰,将其他的放到第一位:

import random
?
list = [1, 2, 3, 4, 5, 6, 7]
?
while True:
 ? ?if len(list) == 1: ? ?# pop的只剩最后一位了
 ? ? ? ?print('游戏结束,{}获得了胜利'.format(list[0])) ?
 ? ? ? ?break
 ? ?hit = random.randint(1, 3) ? # 随机数指定倒数第几位淘汰
 ? ?while hit >= 1:
 ? ? ? ?pop1 = list.pop() ? ?# 取出后面的数将它放到最前面
 ? ? ? ?if hit == 1:
 ? ? ? ? ? ?print('{}被淘汰了'.format(pop1)) ?# hit等于1的时候,就是该淘汰的人
 ? ? ? ? ? ?break
 ? ? ? ?list.insert(0, pop1)
 ? ? ? ?hit -= 1

链表:

class Node():
 ? ?def __init__(self, date=None, next=None):
 ? ? ? ?self._data = date
 ? ? ? ?self._next = next
?
 ? ?def setDate(self, Newdata):
 ? ? ? ?self._data = Newdata
?
 ? ?def setNext(self, NewNext):
 ? ? ? ?self._next = NewNext
?
 ? ?def getDate(self):
 ? ? ? ?return self._data
?
 ? ?def getNext(self):
 ? ? ? ?return self._next
?
?
class linkList():
 ? ?def __init__(self):
 ? ? ? ?self._head = Node()
 ? ? ? ?self._length = 0
?
 ? ?def tail_add(self, Newdata):
 ? ? ? ?newdate = Node(Newdata, None)
 ? ? ? ?if self._length == 0:
 ? ? ? ? ? ?self._head = newdate
 ? ? ? ? ? ?self._length = 1
 ? ? ? ?else:
 ? ? ? ? ? ?current = self._head
 ? ? ? ? ? ?while current.getNext() != None:
 ? ? ? ? ? ? ? ?current = current.getNext()
 ? ? ? ? ? ? ? ?current.setnext(newdate)
 ? ? ? ? ? ? ? ?self._length += 1

图:

A机场可以到达BCD

B机场可以到无

C机场可以到D

D机场可以到A

import numpy as np
?
?
class AdjacencyMatrix():
 ? ?def __init__(self, n=2):
 ? ? ? ?self.Matrix = np.zeros([n, n])
?
 ? ?def get_matrix(self):
 ? ? ? ?for i in self.Matrix:
 ? ? ? ? ? ?print(i)
?
 ? ?def add(self, x, y, value):
 ? ? ? ?self.Matrix[x, y] = value ?# 设置节点之间的关系
?
?
airport = AdjacencyMatrix(4) ? ? ? # 4个飞机节点
airport.add(0, 1, 1)
airport.add(0, 2, 1)
airport.add(0, 3, 1)
airport.add(2, 3, 1)
airport.add(3, 1, 1)
airport.get_matrix()

组合总和

给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。

candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。

示例 1:

输入:candidates = [2,3,6,7], target = 7 输出:[[2,2,3],[7]] 解释: 2 和 3 可以形成一组候选,2 + 2 + 3 = 7 。注意 2 可以使用多次。 7 也是一个候选, 7 = 7 。

思路:还是使用回溯算法进行遍历,主要是控制结束条件

class Solution(object):
 ? ?def combinationSum(self, candidates, target):
 ? ? ? ?"""
 ? ? ?  :type candidates: List[int]
 ? ? ?  :type target: int
 ? ? ?  :rtype: List[List[int]]
 ? ? ?  """
 ? ? ? ?res = []
 ? ? ? ?if not candidates or (len(candidates) == 1 and candidates[0] > target):
 ? ? ? ? ? ?return res ? # 如果列表为空或者一个数且大于target,直接返回
 ? ? ? ?n = len(candidates) ?
?
 ? ? ? ?def backtrack(i, sum, list): ? ?
 ? ? ? ? ? ?if sum > target or i == n: ?# 当和大于target 或者 最后一个数的时候,返回
 ? ? ? ? ? ? ? ?return
 ? ? ? ? ? ?if sum == target: ? ?# 和为target,将它加到加到列表里
 ? ? ? ? ? ? ? ?res.append(list)
 ? ? ? ? ? ? ? ?return
 ? ? ? ? ? ?else:
 ? ? ? ? ? ? ? ?for m in range(i, n): ?# 当和小于target,进行循环
 ? ? ? ? ? ? ? ? ?
 ? ? ? ? ? ? ? ? ? ?if sum > target: ?# 在过程中,sum>target,return
 ? ? ? ? ? ? ? ? ? ? ? ?break
 ? ? ? ? ? ? ? ? ? ?backtrack(m, sum + candidates[m], list + [candidates[m]]) ?
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?# list 不断的存放累加
?
 ? ? ? ?backtrack(0, 0, [])
 ? ? ? ?return res

全排列

给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案

示例 1:

输入:nums = [1,2,3] 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

思路:我们要注意到结果和nums的长度都是一样,换了位置而已,轮流取一个加进去,在递归调用,拿去数据

class Solution(object):
 ? ?def permute(self, nums):
 ? ? ? ?"""
 ? ? ?  :type nums: List[int]
 ? ? ?  :rtype: List[List[int]]
 ? ? ?  """
 ? ? ? ?res = []
?
 ? ? ? ?def backtrack(nums, list1): ?
 ? ? ? ? ? ?if not nums: ? ? ?
 ? ? ? ? ? ? ? ?res.append(list1)
 ? ? ? ? ? ? ? ?return
 ? ? ? ? ? ?for i in range(len(nums)):
 ? ? ? ? ? ? ? ?backtrack(nums[:i] + nums[i + 1:], list1 + [nums[i]])
?
 ? ? ? ?backtrack(nums, [])
 ? ? ? ?return res

删除排序链表中的重复元素

给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。

示例 1:

输入:head = [1,1,2] 输出:[1,2] 示例 2:

# Definition for singly-linked list.
# class ListNode(object):
# ? ? def __init__(self, val=0, next=None):
# ? ? ? ? self.val = val
# ? ? ? ? self.next = next
class Solution(object):
 ? ?def deleteDuplicates(self, head):
 ? ? ? ?"""
 ? ? ?  :type head: ListNode
 ? ? ?  :rtype: ListNode
 ? ? ?  """
 ? ? ? ?if head==None:
 ? ? ? ? ? ?return None ?# 当为空时直接返回
 ? ? ? ?else:
 ? ? ? ? ? ?node = head ? ?# node指向head头结点 
 ? ? ? ? ? ?while(node.next!= None): ?# 不是最后一个节点
 ? ? ? ? ? ? ? ?if node.val==node.next.val: ? ?# 由于是排好序了的,相同下一个数据等于本数据
 ? ? ? ? ? ? ? ? ? ?node.next = node.next.next ?# 改变指针到下一个的下一个
 ? ? ? ? ? ? ? ?else:
 ? ? ? ? ? ? ? ? ? ?node = node.next ?# 不然就指针向后移动进行遍历
 ? ? ? ?return head

第一个只出现一次的字符

在字符串 s 中找出第一个只出现一次的字符。如果没有,返回一个单空格。 s 只包含小写字母。

示例 1:

输入:s = "abaccdeff" 输出:'b'

思路:一个数组用于暂时存放数据,另外一个集合用于存放重复出现的数字,第二次出现的数据就从数组里拿出来,放到集合中

class Solution(object):
 ? ?def firstUniqChar(self, s):
 ? ? ? ?once = []
 ? ? ? ?times = set()
 ? ? ? ?if s == '': ? ? # 输入为空字符串情况
 ? ? ? ? ? ?return ' '
 ? ? ? ?for i in s: ? ?# 遍历字符串
 ? ? ? ? ? ?if i in once: ? ?# 先判断在不在once里,在就删除,添加到黑名单times里
 ? ? ? ? ? ? ? ?once.remove(i)
 ? ? ? ? ? ? ? ?times.add(i)
 ? ? ? ? ? ?if i not in times: # 不在once,也不再times里,加入once里
 ? ? ? ? ? ? ? ?once.append(i)
?
 ? ? ? ?if once==[]:
 ? ? ? ? ? ?return ' '
 ? ? ? ?else:
 ? ? ? ? ? ?return once[0]

机器人的运动范围

地上有一个m行n列的方格,从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外),也不能进入行坐标和列坐标的数位之和大于k的格子。例如,当k为18时,机器人能够进入方格 [35, 37] ,因为3+5+3+7=18。但它不能进入方格 [35, 38],因为3+5+3+8=19。请问该机器人能够到达多少个格子?

示例 1:

输入:m = 2, n = 3, k = 1 输出:3

class Solution(object):
 ? ?def movingCount(self, m, n, k):
 ? ? ? ?"""
 ? ? ?  :type m: int
 ? ? ?  :type n: int
 ? ? ?  :type k: int
 ? ? ?  :rtype: int
 ? ? ?  """
 ? ? ? ?def back(i, j, s):
 ? ? ? ? ? ?if not 0<=i<m or not 0<=j< n or  (i//10 + i%10 + j//10 + j%10) > k or (i, j) in visited: ?
 ? ? ? ? ? ? ? ?return 0
 ? ? ? ? ? ?visited.add((i, j))
 ? ? ? ? ? ?return 1 + back(i + 1, j, s) + back(i, j - 1, s) + back(i + 1, j, s) + back(i, j + 1, s)
 ? ? ? ?visited = set()
 ? ? ? ?return back(0,0,k)
?
 ? ? ? 

剑指 Offer 26. 树的子结构

输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)

B是A的子结构, 即 A中有出现和B相同的结构和节点值。

例如: 给定的树 A:

 3
/ \

4 5 / \ 1 2 给定的树 B:

4 / 1 返回 true,因为 B 与 A 的一个子树拥有相同的结构和节点值。

示例 1:

输入:A = [1,2,3], B = [3,1] 输出:false

思路:使用先序遍历的方法,当B为空的时候,说明遍历完成,作为函数的出口,

返回的False的2中情况:

  • 当a为空,b不为空的时候,说明b的数据多于a的,返回false

  • 当值不相等的时候,返回

# 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 isSubStructure(self, A, B):
 ? ? ? ?"""
 ? ? ?  :type A: TreeNode
 ? ? ?  :type B: TreeNode
 ? ? ?  :rtype: bool
 ? ? ?  """
 ? ? ? ?def cur(A, B): ?
 ? ? ? ? ? ?if not B: return True ? # b为空,遍历结束
 ? ? ? ? ? ?if not A or A.val != B.val or (not A and not B): return False
 ? ? ? ? ? ?return cur(A.left, B.left) and cur(A.right, B.right) 
?
 ? ? ? ?return bool(A and B) and (cur(A,B) or self.isSubStructure(A.left,B) or self.isSubStructure(A.right,B)) ?# 判断a或者b是否为空的条件, bool(A and B)

剑指 Offer 27. 二叉树的镜像

请完成一个函数,输入一个二叉树,该函数输出它的镜像。

例如输入:

 4

/ \ 2 7 / \ / \ 1 3 6 9 镜像输出:

 4

/ \ 7 2 / \ / \ 9 6 3 1

示例 1:

输入:root = [4,2,7,1,3,6,9] 输出:[4,7,2,9,6,3,1

思路:主要是回溯算法,将一边的数据暂存,然后将数据进行交换。回溯遍历,结束的条件为不存在节点,即遍历到底了,如果不暂存,交换后就会对原来的数据进行覆盖

# 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 mirrorTree(self, root):
 ? ? ? ?if not root: return ?# 遍历完
 ? ? ? ?tmp = root.left ?# 暂存数据
 ? ? ? ?root.left = self.mirrorTree(root.right) 
 ? ? ? ?root.right = self.mirrorTree(tmp)
 ? ? ? ?return root

剑指 Offer 28. 对称的二叉树

请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。

例如,二叉树 [1,2,2,3,4,4,3] 是对称的。

1

/ \ 2 2 / \ / \ 3 4 4 3 但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的:

1

/ \ 2 2 \ \ 3 3

# 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 isSymmetric(self, root):
 ? ? ? ?"""
 ? ? ?  :type root: TreeNode
 ? ? ?  :rtype: bool
 ? ? ?  """
 ? ? ? ?def search(l, r):
 ? ? ? ? ? ?if not l and not r: return True
 ? ? ? ? ? ?if not l or not r or l.val != r.val: return False
 ? ? ? ? ? ?return search(l.left, r.right) and search(l.right, r.left)
?
 ? ? ? ?return not root or search(root.left, root.right)

二维数组中的查找

在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

示例:

现有矩阵 matrix 如下:

[ [1, 4, 7, 11, 15], [2, 5, 8, 12, 19], [3, 6, 9, 16, 22], [10, 13, 14, 17, 24], [18, 21, 23, 26, 30] ] 给定 target = 5,返回 true。

思路:由于给定的二维数组是从上到下递增,从左到右递增,那么以18这个值为mid,进行比对,如果大于目标值,就向上,如果小于目标值,就向右

class Solution(object):
 ? ?def findNumberIn2DArray(self, matrix, target):
 ? ? ? ?c, m = len(matrix) - 1, 0
 ? ? ? ?while c >= 0 and m < len(matrix[0]): ?# len(matrix[0])可能为空,所以把 c >= 0放在前面
 ? ? ? ? ? ?if matrix[c][m] > target: ?# 大于目标值
 ? ? ? ? ? ? ? ?c -= 1 ? ? ? ? ? ? # 向上移动一行
 ? ? ? ? ? ?elif matrix[c][m] < target: ? # 小于目标值
 ? ? ? ? ? ? ? ?m += 1 ? ? ? ? ? ? ? ? ? # 向左移动一个位置
 ? ? ? ? ? ?else:
 ? ? ? ? ? ? ? ?return True
 ? ? ? ?return False

青蛙跳台阶问题

一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。

答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。

示例 1:

输入:n = 2 输出:2

思路:斐波那契,看到1或者2的时候,要警惕出来

class Solution(object):
 ? ?def numWays(self, n):
 ? ? ? ?a = 1
 ? ? ? ?b = 1
 ? ? ? ?for _ in range(n):
 ? ? ? ? ? ?a,b= b,a+b ?
 ? ? ? ?return a% 1000000007

矩阵中的路径

给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。

单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

例如,在下面的 3×4 的矩阵中包含单词 "ABCCED"(单词中的字母已标出)。

示例 1:

输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED" 输出:true 示例 2:

class Solution(object):
 ? ?def exist(self, board, word):
 ? ? ? ?"""
 ? ? ?  :type board: List[List[str]]
 ? ? ?  :type word: str
 ? ? ?  :rtype: bool
 ? ? ?  """
 ? ? ? ?def dfs(i, j, k):
 ? ? ? ? ? ?if not 0<=i<len(board) or not 0<=j<len(board[0])or board[i][j]!= word[k]: 
 ? ? ? ? ? ? ? ?return False # 当i,j不属于范围或者值不等于word[i],返回
 ? ? ? ? ? ?if k == len(word) - 1: return True # k为长度-1,表示全部进行了遍历
 ? ? ? ? ? ?board[i][j] = '' ?# 将遍历过的替换为‘’,防止重复遍历
 ? ? ? ? ? ?res = dfs(i + 1, j, k+1)or dfs(i-1,j,k+1) or dfs(i,j+1,k+1)or dfs(i,j-1,k+1)#进行上下左右的试探,只要找得到就会为True
 ? ? ? ? ? ?board[i][j] = word[k] # 将替换了的数据替换回去,避免影响后续遍历
 ? ? ? ? ? ?return res ? 
?
 ? ? ? ?for i in range(len(board)):
 ? ? ? ? ? ?for j in range(len(board[0])):
 ? ? ? ? ? ? ? ?if dfs(i,j,0):
 ? ? ? ? ? ? ? ? ? ?return True ?# 全部进行遍历,因为每一个数都可能是开始,只要res为True,返回真
 ? ? ? ?return False

给定一个字符串,求出全排:(要求不重复)

class Solution(object):
 ? ?def permutation(self, s):
 ? ? ? ?"""
 ? ? ?  :type s: str
 ? ? ?  :rtype: List[str]
 ? ? ?  """
 ? ? ? ?c, res = list(s), []
?
 ? ? ? ?def bracktrack(x):
 ? ? ? ? ? ?if x == len(c) - 1:
 ? ? ? ? ? ? ? ?res.append(''.join(c))
 ? ? ? ? ? ?p = set()
 ? ? ? ? ? ?for i in range(x,len(c)):
 ? ? ? ? ? ? ? ?if c[i] in p: continue
 ? ? ? ? ? ? ? ?p.add(c[i])
 ? ? ? ? ? ? ? ?c[i], c[x] = c[x], c[i]
 ? ? ? ? ? ? ? ?bracktrack(x+1)
 ? ? ? ? ? ? ? ?c[x], c[i] = c[i], c[x]
 ? ? ? ?bracktrack(0)
 ? ? ? ?return res
?
s = Solution()
m = s.permutation('abc')
print(m)
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-06-01 15:26:10  更:2022-06-01 15:27:00 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 14:25:11-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码