| |
|
开发:
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: 给你一幅由 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] ? 给你一个字符串 示例 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 解释:所有可能的分法(忽略元素顺序)为:
思路:两两拆分,返回最小,实际上就是将排序之后的偶数项相加: 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 = 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) 杨辉三角给定一个非负整数 示例 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给定一个非负索引 示例 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()转换为列表,进行遍历,对每一个单词单独进行反转,最后转成字符串在返回 删除排序数组中的重复项给你一个 升序排列 的数组 示例 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 在排序数组中查找元素的第一个和最后一个位置 给定一个按照升序排列的整数数组 示例 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 个结点,并且返回链表的头结点 示例 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 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。
思路:还是使用回溯算法进行遍历,主要是控制结束条件 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中情况:
# 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) |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
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- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |