代码随想录算法训练营第二十五天 | 读PDF复习环节3

读PDF复习环节3

  • 本博客的内容只是做一个大概的记录,整个PDF看下来,内容上是不如代码随想录网站上的文章全面的,并且PDF中有些地方的描述,是很让我疑惑的,在困扰我很久后,无意间发现,其网站上的讲解完全符合我的思路。这次看完这些PDF后,暂时一段时间内不会再看了,要复习还是依靠,代码随想录网站,视频,和我自己写的博客吧
  • 回溯算法章节,这算是我掌握的还行的一个章节了。
    • 组合
    • 组合总和 III
    • 电话号码的字母组合
    • 组合总和
      • 本题,代码随想录的剪枝策略是,排序之后加剪枝,可以,不符合条件直接跳出当层for循环了。
    • 组合总和II
      • 树层去重,used[i-1] = False 。树枝去重,used[i-1] = True .
    • 分割回文串
    • 复原IP地址
    • 子集
      • 求组合,就要用到 idx ,求排列,不需要 idx , 而且本题不需要 used 数组,idx 已经成功控制了。
    • 子集II
    • 递增子序列
      • 本题太具有迷惑性了,一开始还真没注意!本题给的示例都是排好序的,让我误以为可以使用之前的去重逻辑!实则不然,因为求的是递增子序列,这意味着我们不能对数组进行排序操作,所以不能使用之前的去重逻辑。要使用新的,在递归函数中每次都声明的,哈希(集合)去重逻辑,我不喜欢用set,我喜欢用哈希。
      • 代码随想录的代码
    • 全排列
      • 求排列,不需要 idx , 递归中每次都是从0开始遍历,但要用used数组,来表示哪些元素已经被使用过。
    • 全排列 II
      • 小小去重,可笑可笑
      • 但是这道题的去重很有意思,要去看代码随想录的解答。
    • 回溯算法去重问题的另一种写法
      • 可以看看,核心思想是,讲解树层去重和树枝去重。
    • 重新安排行程
      • 再看依旧是不会
    • N皇后
      • 前几天写过了,核心思想就是,皇后一定是一行一行放的,每行放一个,所以可以用一个idx来控制当前是第几行,只要for循环遍历每个列位置就可以了,另外,在判断皇后是否合法时,我们只需要知道每个皇后的位置就可以了,不需要传入整个棋盘,那样太复杂了。
    • 数独
      • 本题的要点在于,就是在每个递归函数中,都使用三层,从0开始遍历的for循环,遍历行,遍历列,遍历数字,利用棋盘中,该位置是否是空,来判断是否在该位置填入数字,这样的编程逻辑是非常自然的。如果是想用idx来控制当前输入到了第几行第几列,那样就太麻烦了!遇到数字就continue,多跑几次什么都不做的for循环是无所谓的!
      • 同样,在上面的编写逻辑下,判断是否合法也是较为容易的,只需要传入当前参数,每层循环的 i j k ,去判断,同行,同列,同小块,是否合法即可。

本博客的内容只是做一个大概的记录,整个PDF看下来,内容上是不如代码随想录网站上的文章全面的,并且PDF中有些地方的描述,是很让我疑惑的,在困扰我很久后,无意间发现,其网站上的讲解完全符合我的思路。这次看完这些PDF后,暂时一段时间内不会再看了,要复习还是依靠,代码随想录网站,视频,和我自己写的博客吧

回溯算法章节,这算是我掌握的还行的一个章节了。

组合

其中使用的剪枝技巧值得学习。
在这里插入图片描述

组合总和 III

class Solution:
    def combinationSum3(self, k: int, n: int) -> List[List[int]]:
        self.res = []
        path = []
        idx = 1
        self.backtracking(k,n,idx,path)
        return self.res

    def backtracking(self,k,n,idx,path):
        if len(path)==k :
            if n == 0 :
                self.res.append(path.copy())
                return
            else :
                return
        # 小小剪枝
        for i in range(idx,10-(k-len(path))+1):
            # 小小剪枝
            if n-i < 0 :
                continue
            else :
                path.append(i)
                self.backtracking(k,n-i,i+1,path)
                path.pop()

        return 

电话号码的字母组合

只要用 idx 来控制当前应该取第几个数字,就只需要一层循环了,而不是之前我习惯的两层循环。

class Solution:
    def letterCombinations(self, digits: str) -> List[str]:
        if digits == '' :
            return []
        self.dict = {'1' : '', '0' : '' , '#' : '' , '*' : '' ,
        '2':'abc' , '3':'def' , '4':'ghi' , '5':'jkl', '6':'mno' ,
        '7':'pqrs','8':'tuv','9':'wxyz'}

        self.res = []
        path = []
        n = len(digits)
        idx = 0
        self.backtracking(digits,n,idx,path)
        return self.res


    def backtracking(self,digits,n,idx,path):
        if len(path) == n :
            self.res.append(''.join(path))
            return
		# 取当前的数字
        number = digits[idx]
        ss = self.dict[number]
        m = len(ss)
        # 在当前数字对应的字符串中,从0开始遍历
        for i in range(m):
            path.append(ss[i])
            self.backtracking(digits,n,idx+1,path)
            path.pop()

组合总和

本题需要注意的是,虽然元素可以重复,但是必须要有idx,idx是保证,遍历一直是正序的,不会走回头路。

class Solution:
    def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
        self.res = []
        path = []
        n = len(candidates)
        idx = 0
        self.backtracking(candidates,n,target,idx,path)
        return self.res



    def backtracking(self,candidates,n,target,idx,path):
        if target == 0 :
            self.res.append(path.copy())
            return

        if target < 0 :
            return

        for i in range(idx,n):
            if target < candidates[i] :
                continue
            path.append(candidates[i])
            # 注意这里,传入 idx 的区别,因为元素可以重复,所以是 i , 不是 i+1
            # 但是也必须要有idx !!! 
            self.backtracking(candidates,n,target-candidates[i],i,path)
            path.pop()

在这里插入图片描述

本题,代码随想录的剪枝策略是,排序之后加剪枝,可以,不符合条件直接跳出当层for循环了。

class Solution:

    def backtracking(self, candidates, target, total, startIndex, path, result):
        if total == target:
            result.append(path[:])
            return

        for i in range(startIndex, len(candidates)):
            if total + candidates[i] > target:
                break
            total += candidates[i]
            path.append(candidates[i])
            self.backtracking(candidates, target, total, i, path, result)
            total -= candidates[i]
            path.pop()

    def combinationSum(self, candidates, target):
        result = []
        candidates.sort()  # 需要排序
        self.backtracking(candidates, target, 0, 0, [], result)
        return result

组合总和II

剪枝+used数组去重。

class Solution:
    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
        candidates.sort()
        n = len(candidates)
        self.res = []
        path = []
        used = [False]*n
        idx = 0
        self.backtracking(candidates,target,n,idx,path,used)

        return self.res

    def backtracking(self,candidates,target,n,idx,path,used):
        if target == 0 :
            self.res.append(path.copy())
            return
        if target < 0 :
            return 

        for i in range(idx,n):
            if candidates[i] > target :
                break
            if i > 0 and used[i-1] == False and candidates[i]==candidates[i-1]:
                continue
            path.append(candidates[i])
            used[i] = True
            self.backtracking(candidates,target-candidates[i],n,i+1,path,used)
            used[i] = False
            path.pop()

树层去重,used[i-1] = False 。树枝去重,used[i-1] = True .

代码随想录的代码

class Solution:


    def backtracking(self, candidates, target, total, startIndex, used, path, result):
        if total == target:
            result.append(path[:])
            return

        for i in range(startIndex, len(candidates)):
            # 对于相同的数字,只选择第一个未被使用的数字,跳过其他相同数字
            if i > startIndex and candidates[i] == candidates[i - 1] and not used[i - 1]:
                continue

            if total + candidates[i] > target:
                break

            total += candidates[i]
            path.append(candidates[i])
            used[i] = True
            self.backtracking(candidates, target, total, i + 1, used, path, result)
            used[i] = False
            total -= candidates[i]
            path.pop()

    def combinationSum2(self, candidates, target):
        used = [False] * len(candidates)
        result = []
        candidates.sort()
        self.backtracking(candidates, target, 0, 0, used, [], result)
        return result

分割回文串

注意分割区间定义即可,左闭右闭。

class Solution:
    def partition(self, s: str) -> List[List[str]]:
        self.res = []
        path = []
        n = len(s)
        idx = 0
        self.backtracking(s,n,idx,path)

        return self.res

    def backtracking(self,s,n,idx,path):
        if idx >= n :
            self.res.append(path.copy())
            return 
        # 这里注意细节就好,i就是要取到n-1
        # 加入s='aa',s[1:2]='a',索引下标,是不包括最后一个值的
        for i in range(idx,n):
            # 注意回文子串区间定义:[idx,i],i为分割线
            temp = s[idx:i+1]
            if self.is_right(temp):
                path.append(temp)
                self.backtracking(s,n,i+1,path)
                path.pop()

    def is_right(self,temp):
        left = 0
        right = len(temp)-1
        while left < right :
            if temp[left]!=temp[right]:
                return False
            left += 1
            right -= 1 

        return True

还可以提前使用动态规划的方法,判断出给字符串的所有子串是否是回文串,然后将结果储存起来。核心代码就是,先从下到上遍历,再从左到右遍历,一共需要考虑三种情况,会导致 dp[i][j] 是回文串,dp[i][j] 代表字符串中 [i,j] 的子串,是不是回文串。

class Solution:
    def partition(self, s: str) -> List[List[str]]:
        result = []
        isPalindrome = [[False] * len(s) for _ in range(len(s))]  # 初始化isPalindrome矩阵
        self.computePalindrome(s, isPalindrome)
        self.backtracking(s, 0, [], result, isPalindrome)
        return result

    def backtracking(self, s, startIndex, path, result, isPalindrome):
        if startIndex >= len(s):
            result.append(path[:])
            return

        for i in range(startIndex, len(s)):
            if isPalindrome[startIndex][i]:   # 是回文子串
                substring = s[startIndex:i + 1]
                path.append(substring)
                self.backtracking(s, i + 1, path, result, isPalindrome)  # 寻找i+1为起始位置的子串
                path.pop()           # 回溯过程,弹出本次已经添加的子串

    def computePalindrome(self, s, isPalindrome):
        for i in range(len(s) - 1, -1, -1):  # 需要倒序计算,保证在i行时,i+1行已经计算好了
            for j in range(i, len(s)):
                if j == i:
                    isPalindrome[i][j] = True
                elif j - i == 1:
                    isPalindrome[i][j] = (s[i] == s[j])
                else:
                    isPalindrome[i][j] = (s[i] == s[j] and isPalindrome[i+1][j-1])

复原IP地址

class Solution:
    def restoreIpAddresses(self, s: str) -> List[str]:
        self.res = []
        path = []
        idx = 0
        n = len(s)
        self.backtacking(s,n,idx,path)
        return self.res

    def backtacking(self,s,n,idx,path):
        if idx >= n :
            if len(path)==4:
                self.res.append('.'.join(path))
                return
            else :
                return
        if len(path)==3 :
            temp = s[idx:n]
            if self.is_right(temp):
                path.append(temp)
                self.backtacking(s,n,n,path)
                path.pop()
        else :
            for i in range(idx,n):  
                temp = s[idx:i+1]
                if self.is_right(temp):
                    path.append(temp)
                    self.backtacking(s,n,i+1,path)
                    path.pop()

    def is_right(self,temp):
        n = len(temp)
        if temp[0] == '0' and n > 1 :
            return False
        if int(temp) > 255 or int(temp) < 0 :
            return False
        return True

我觉得我还剪了一下枝,挺好,

代码随想录的代码:

class Solution:
    def restoreIpAddresses(self, s: str) -> List[str]:
        results = []
        self.backtracking(s, 0, [], results)
        return results

    def backtracking(self, s, index, path, results):
        if index == len(s) and len(path) == 4:
            results.append('.'.join(path))
            return

        if len(path) > 4:  # 剪枝
            return

        for i in range(index, min(index + 3, len(s))):
            if self.is_valid(s, index, i):
                sub = s[index:i+1]
                path.append(sub)
                self.backtracking(s, i+1, path, results)
                path.pop()

    def is_valid(self, s, start, end):
        if start > end:
            return False
        if s[start] == '0' and start != end:  # 0开头的数字不合法
            return False
        num = int(s[start:end+1])
        return 0 <= num <= 255

子集

冗余的代码,本题不需要 used 数组,idx 已经可以控制,不出现重复了。

class Solution:
    def subsets(self, nums: List[int]) -> List[List[int]]:
        self.res = []
        path = []
        n = len(nums)
        used = [False]*n
        idx = 0
        self.backtracking(nums,n,idx,used,path)
        return self.res

    def backtracking(self,nums,n,idx,used,path):
        self.res.append(path.copy())

        # 本题还是要有idx
        for i in range(idx,n):
            if used[i]==False :
                used[i]=True
                path.append(nums[i])
                self.backtracking(nums,n,i+1,used,path)
                path.pop()
                used[i]=False

在这里插入图片描述

求组合,就要用到 idx ,求排列,不需要 idx , 而且本题不需要 used 数组,idx 已经成功控制了。

代码随想录的代码:

class Solution:
    def subsets(self, nums):
        result = []
        path = []
        self.backtracking(nums, 0, path, result)
        return result

    def backtracking(self, nums, startIndex, path, result):
        result.append(path[:])  # 收集子集,要放在终止添加的上面,否则会漏掉自己
        # if startIndex >= len(nums):  # 终止条件可以不加
        #     return
        for i in range(startIndex, len(nums)):
            path.append(nums[i])
            self.backtracking(nums, i + 1, path, result)
            path.pop()

子集II

直接套用之前的去重逻辑。

class Solution:
    def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:
        self.res = []
        path = []
        nums.sort()
        n = len(nums)
        used = [False]*n
        idx = 0
        self.backtracking(nums,n,idx,used,path)
        return self.res

    def backtracking(self,nums,n,idx,used,path):
        self.res.append(path.copy())

        # 本题还是要有idx
        for i in range(idx,n):
            if i > 0 and used[i-1]==False and nums[i-1]==nums[i]:
                continue
            else:   
                used[i]=True
                path.append(nums[i])
                self.backtracking(nums,n,i+1,used,path)
                path.pop()
                used[i]=False

递增子序列

本题太具有迷惑性了,一开始还真没注意!本题给的示例都是排好序的,让我误以为可以使用之前的去重逻辑!实则不然,因为求的是递增子序列,这意味着我们不能对数组进行排序操作,所以不能使用之前的去重逻辑。要使用新的,在递归函数中每次都声明的,哈希(集合)去重逻辑,我不喜欢用set,我喜欢用哈希。

class Solution:
    def findSubsequences(self, nums: List[int]) -> List[List[int]]:
        self.res = []
        path = []
        idx = 0
        n = len(nums)
        
        self.backtracking(nums,n,idx,path)
        return self.res

    def backtracking(self,nums,n,idx,path):
        if len(path)>=2:
            self.res.append(path.copy())

        used = [False]*201

        for i in range(idx,n):
            if used[100+nums[i]] == True:
                continue
            if path==[] or nums[i] >= path[-1] :
                path.append(nums[i])
                used[100+nums[i]] = True
                self.backtracking(nums,n,i+1,path)
                path.pop()

代码随想录的代码

递增子序列

class Solution:
    def findSubsequences(self, nums):
        result = []
        path = []
        self.backtracking(nums, 0, path, result)
        return result
    
    def backtracking(self, nums, startIndex, path, result):
        if len(path) > 1:
            result.append(path[:])  # 注意要使用切片将当前路径的副本加入结果集
            # 注意这里不要加return,要取树上的节点
        
        uset = set()  # 使用集合对本层元素进行去重
        for i in range(startIndex, len(nums)):
            if (path and nums[i] < path[-1]) or nums[i] in uset:
                continue
            
            uset.add(nums[i])  # 记录这个元素在本层用过了,本层后面不能再用了
            path.append(nums[i])
            self.backtracking(nums, i + 1, path, result)
            path.pop()

class Solution:
    def findSubsequences(self, nums):
        result = []
        path = []
        self.backtracking(nums, 0, path, result)
        return result

    def backtracking(self, nums, startIndex, path, result):
        if len(path) > 1:
            result.append(path[:])  # 注意要使用切片将当前路径的副本加入结果集
        
        used = [0] * 201  # 使用数组来进行去重操作,题目说数值范围[-100, 100]
        for i in range(startIndex, len(nums)):
            if (path and nums[i] < path[-1]) or used[nums[i] + 100] == 1:
                continue  # 如果当前元素小于上一个元素,或者已经使用过当前元素,则跳过当前元素
            
            used[nums[i] + 100] = 1  # 标记当前元素已经使用过
            path.append(nums[i])  # 将当前元素加入当前递增子序列
            self.backtracking(nums, i + 1, path, result)
            path.pop()

全排列

求排列,不需要 idx , 递归中每次都是从0开始遍历,但要用used数组,来表示哪些元素已经被使用过。

class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        self.res = []
        path = []
        n = len(nums)
        used = [False]*n
        
        self.backtracking(nums,n,used,path)
        return self.res

    def backtracking(self,nums,n,used,path):
        if len(path)==n:
            self.res.append(path.copy())
            return

        
        for i in range(n):
            if used[i]==False :
                used[i]=True
                path.append(nums[i])
                self.backtracking(nums,n,used,path)
                path.pop()
                used[i]=False

全排列 II

小小去重,可笑可笑

lass Solution:
    def permuteUnique(self, nums: List[int]) -> List[List[int]]:
        self.res = []
        path = []
        n = len(nums)
        nums.sort()
        used = [False]*n
        
        self.backtracking(nums,n,used,path)
        return self.res

    def backtracking(self,nums,n,used,path):
        if len(path)==n:
            self.res.append(path.copy())
            return

        
        for i in range(n):
            if i > 0 and used[i-1] == False and nums[i-1]==nums[i]:
                continue
            if used[i]==False:
                used[i]=True
                path.append(nums[i])
                self.backtracking(nums,n,used,path)
                path.pop()
                used[i]=False

但是这道题的去重很有意思,要去看代码随想录的解答。

全排列 II

回溯算法去重问题的另一种写法

可以看看,核心思想是,讲解树层去重和树枝去重。

回溯算法去重问题的另一种写法

重新安排行程

再看依旧是不会

重新安排行程

class Solution:
    def findItinerary(self, tickets: List[List[str]]) -> List[str]:
        tickets.sort() # 先排序,这样一旦找到第一个可行路径,一定是字母排序最小的
        used = [0] * len(tickets)
        path = ['JFK']
        results = []
        self.backtracking(tickets, used, path, 'JFK', results)
        return results[0]
    
    def backtracking(self, tickets, used, path, cur, results):
        if len(path) == len(tickets) + 1:  # 终止条件:路径长度等于机票数量+1
            results.append(path[:])  # 将当前路径添加到结果列表
            return True
        
        for i, ticket in enumerate(tickets):  # 遍历机票列表
            if ticket[0] == cur and used[i] == 0:  # 找到起始机场为cur且未使用过的机票
                used[i] = 1  # 标记该机票为已使用
                path.append(ticket[1])  # 将到达机场添加到路径中
                state = self.backtracking(tickets, used, path, ticket[1], results)  # 递归搜索
                path.pop()  # 回溯,移除最后添加的到达机场
                used[i] = 0  # 标记该机票为未使用
                if state:
                    return True  # 只要找到一个可行路径就返回,不继续搜索
from collections import defaultdict

class Solution:
    def findItinerary(self, tickets: List[List[str]]) -> List[str]:
        targets = defaultdict(list)  # 构建机场字典
        for ticket in tickets:
            targets[ticket[0]].append(ticket[1])
        for airport in targets:
            targets[airport].sort()  # 对目的地列表进行排序

        path = ["JFK"]  # 起始机场为"JFK"
        self.backtracking(targets, path, len(tickets))
        return path

    def backtracking(self, targets, path, ticketNum):
        if len(path) == ticketNum + 1:
            return True  # 找到有效行程

        airport = path[-1]  # 当前机场
        destinations = targets[airport]  # 当前机场可以到达的目的地列表
        for i, dest in enumerate(destinations):
            targets[airport].pop(i)  # 标记已使用的机票
            path.append(dest)  # 添加目的地到路径
            if self.backtracking(targets, path, ticketNum):
                return True  # 找到有效行程
            targets[airport].insert(i, dest)  # 回溯,恢复机票
            path.pop()  # 移除目的地
        return False  # 没有找到有效行程

N皇后

前几天写过了,核心思想就是,皇后一定是一行一行放的,每行放一个,所以可以用一个idx来控制当前是第几行,只要for循环遍历每个列位置就可以了,另外,在判断皇后是否合法时,我们只需要知道每个皇后的位置就可以了,不需要传入整个棋盘,那样太复杂了。

代码随想录的代码:

class Solution:
    def solveNQueens(self, n: int) -> List[List[str]]:
        result = []  # 存储最终结果的二维字符串数组

        chessboard = ['.' * n for _ in range(n)]  # 初始化棋盘
        self.backtracking(n, 0, chessboard, result)  # 回溯求解
        return [[''.join(row) for row in solution] for solution in result]  # 返回结果集

    def backtracking(self, n: int, row: int, chessboard: List[str], result: List[List[str]]) -> None:
        if row == n:
            result.append(chessboard[:])  # 棋盘填满,将当前解加入结果集
            return

        for col in range(n):
            if self.isValid(row, col, chessboard):
                chessboard[row] = chessboard[row][:col] + 'Q' + chessboard[row][col+1:]  # 放置皇后
                self.backtracking(n, row + 1, chessboard, result)  # 递归到下一行
                chessboard[row] = chessboard[row][:col] + '.' + chessboard[row][col+1:]  # 回溯,撤销当前位置的皇后

    def isValid(self, row: int, col: int, chessboard: List[str]) -> bool:
        # 检查列
        for i in range(row):
            if chessboard[i][col] == 'Q':
                return False  # 当前列已经存在皇后,不合法

        # 检查 45 度角是否有皇后
        i, j = row - 1, col - 1
        while i >= 0 and j >= 0:
            if chessboard[i][j] == 'Q':
                return False  # 左上方向已经存在皇后,不合法
            i -= 1
            j -= 1

        # 检查 135 度角是否有皇后
        i, j = row - 1, col + 1
        while i >= 0 and j < len(chessboard):
            if chessboard[i][j] == 'Q':
                return False  # 右上方向已经存在皇后,不合法
            i -= 1
            j += 1

        return True  # 当前位置合法

数独

本题的要点在于,就是在每个递归函数中,都使用三层,从0开始遍历的for循环,遍历行,遍历列,遍历数字,利用棋盘中,该位置是否是空,来判断是否在该位置填入数字,这样的编程逻辑是非常自然的。如果是想用idx来控制当前输入到了第几行第几列,那样就太麻烦了!遇到数字就continue,多跑几次什么都不做的for循环是无所谓的!

同样,在上面的编写逻辑下,判断是否合法也是较为容易的,只需要传入当前参数,每层循环的 i j k ,去判断,同行,同列,同小块,是否合法即可。

代码随想录的代码:

class Solution:
    def solveSudoku(self, board: List[List[str]]) -> None:
        """
        Do not return anything, modify board in-place instead.
        """
        self.backtracking(board)

    def backtracking(self, board: List[List[str]]) -> bool:
        # 若有解,返回True;若无解,返回False
        for i in range(len(board)): # 遍历行
            for j in range(len(board[0])):  # 遍历列
                # 若空格内已有数字,跳过
                if board[i][j] != '.': continue
                for k in range(1, 10):
                    if self.is_valid(i, j, k, board):
                        board[i][j] = str(k)
                        if self.backtracking(board): return True
                        board[i][j] = '.'
                # 若数字1-9都不能成功填入空格,返回False无解
                return False
        return True # 有解

    def is_valid(self, row: int, col: int, val: int, board: List[List[str]]) -> bool:
        # 判断同一行是否冲突
        for i in range(9):
            if board[row][i] == str(val):
                return False
        # 判断同一列是否冲突
        for j in range(9):
            if board[j][col] == str(val):
                return False
        # 判断同一九宫格是否有冲突
        start_row = (row // 3) * 3
        start_col = (col // 3) * 3
        for i in range(start_row, start_row + 3):
            for j in range(start_col, start_col + 3):
                if board[i][j] == str(val):
                    return False
        return True

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/51837.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

前端html中让两个或者多个div在一行显示,用style给div加上css样式

文章目录 前言一、怎么让多个div在一行显示 前言 DIV是层叠样式表中的定位技术&#xff0c;全称DIVision&#xff0c;即为划分。有时可以称其为图层。DIV在编程中又叫做整除&#xff0c;即只得商的整数。 DIV元素是用来为HTML&#xff08;标准通用标记语言下的一个应用&#x…

图像处理之hough圆形检测

hough检测原理 点击图像处理之Hough变换检测直线查看 下面直接描述检测圆形的方法 基于Hough变换的圆形检测方法 对于一个半径为 r r r&#xff0c;圆心为 &#xff08; a , b &#xff09; &#xff08;a,b&#xff09; &#xff08;a,b&#xff09;的圆&#xff0c;我们将…

别再分库分表了,试试TiDB!

什么是NewSQL 传统SQL的问题 升级服务器硬件 数据分片 NoSQL 的问题 优点 缺点 NewSQL 特性 NewSQL 的主要特性 三种SQL的对比 TiDB怎么来的 TiDB社区版和企业版 TIDB核心特性 水平弹性扩展 分布式事务支持 金融级高可用 实时 HTAP 云原生的分布式数据库 高度兼…

M 芯片的 macos 系统安装虚拟机 centos7 网络配置

centos 安装之前把网络配置配好或者是把网线插好 第一步找到这个 第二步打开网络适配器 选择图中所指位置 设置好之后 开机启动 centos 第三步 开机以后 编写网卡文件保存 重启网卡就可以了&#xff0c;如果重启网卡不管用&#xff0c;则重启虚拟机即可 “ ifcfg-ens160 ” 这…

HTML快速学习

目录 一、网页元素属性 1.全局属性 2.标签 2.1其他标签 2.2表单标签 2.3图像标签 2.4列表标签 2.5表格标签 2.6文本标签 二、编码 1.字符的数字表示法 2.字符的实体表示法 三、实践一下 一、网页元素属性 1.全局属性 id属性是元素在网页内的唯一标识符。 class…

iOS开发-实现获取下载主题配置动态切换主题

iOS开发-实现获取下载主题配置动态切换主题 iOS开发-实现获取下载主题配置更切换主题&#xff0c;主要是通过请求服务端配置的主题配置、下载主题、解压保存到本地。通知界面获取对应的图片及颜色等。 比如新年主题风格&#xff0c;常见的背景显示红色氛围图片、tabbar显示新…

【002 操作系统】进程的状态及状态转换图?

一、进程的状态 1. 创建状态 2. 就绪状态 3. 运行状态 4. 阻塞状态 5. 终止状态 图源&#xff1a;进程、线程基础知识全家桶&#xff0c;30 张图一套带走_Linux_小林coding_InfoQ写作社区 NULL -> 创建状态&#xff1a;一个新进程被创建时的第一个状态&#xff1b; 创建状态…

LT6911C 是一款HDMI 1.4到双端口MIPIDSI/CSI或者LVDS加音频的一款高性能芯片

LT6911C 1.描述&#xff1a; LT6911C是一款高性能的HDMI1.4到MIPIDSI/CSI/LVDS芯片&#xff0c;用于VR/智能手机/显示器应用程序。对于MIPIDSI/CSI输出&#xff0c;LT6911C具有可配置的单端口或双端口MIPIDSI/CSI&#xff0c;具有1个高速时钟通道和1个~4个高速数据通道&#…

nacos源码打包及相关配置

nacos 本地下载后&#xff0c;需要 install 下&#xff1a; mvn clean install -Dmaven.test.skiptrue -Dcheckstyle.skiptrue -Dpmd.skiptrue -Drat.skiptruenacos源码修改后&#xff0c;重新打包生成压缩包命令&#xff1a;在 distribution 目录中运行&#xff1a; mvn -Pr…

Java 源码打包 降低jar大小

这里写目录标题 Idea maven 插件配置pom.xml 配置启动技巧 Idea maven 插件配置 pom.xml 配置 <build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><!-- 只…

《吐血整理》进阶系列教程-拿捏Fiddler抓包教程(11)-Fiddler设置安卓手机抓包,不会可是万万不行的!

1.简介 Fiddler不但能截获各种浏览器发出的 HTTP 请求&#xff0c;也可以截获各种智能手机发出的HTTP/ HTTPS 请求。 Fiddler能截获 Android 和 Windows Phone 等设备发出的 HTTP/HTTPS 请求。 今天宏哥讲解和分享Fiddler 如何截获安卓移动端发出的 HTTP/HTTPS 请求。 2.环…

Python基于PyTorch实现卷积神经网络回归模型(CNN回归算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 卷积神经网络&#xff0c;简称为卷积网络&#xff0c;与普通神经网络的区别是它的卷积层内的神经元只覆…

抖音seo短视频矩阵系统源码开发解析---多账号授权管理

本文开发语音使用PHP语言开发&#xff0c;梅雨plum框架自主研发&#xff0c;文末另附开发技巧 抖音SEO短视频矩阵系统源码开发解析是一种基于抖音平台的短视频排名优化技术&#xff0c;通过对抖音算法的分析和抖音用户行为的研究&#xff0c;提供一种基于“流量矩阵”的短视频管…

通过STM32内部ADC将烟雾传感器发送的信号值显示在OLED上

一.CubeMX配置 首先我们在CubeMX配置ADC1, 设置一个定时器TIM2定时1s采样一次以及刷新一次OLED&#xff0c; 打开IIC用于驱动OLED显示屏。 二.程序 在Keil5中添加好oled的显示库&#xff0c;以及用来显示的函数、初始化函数、清屏函数等。在主程序中初始化oled,并将其清屏。…

二维深度卷积网络模型下的轴承故障诊断

1.数据集 使用凯斯西储大学轴承数据集&#xff0c;一共有4种负载下采集的数据&#xff0c;每种负载下有10种 故障状态&#xff1a;三种不同尺寸下的内圈故障、三种不同尺寸下的外圈故障、三种不同尺寸下的滚动体故障和一种正常状态 2.模型&#xff08;二维CNN&#xff09; 使…

现代C++中的从头开始深度学习:激活函数

一、说明 让我们通过在C中实现激活函数来获得乐趣。人工神经网络是生物启发模型的一个例子。在人工神经网络中&#xff0c;称为神经元的处理单元被分组在计算层中&#xff0c;通常用于执行模式识别任务。 在这个模型中&#xff0c;我们通常更喜欢控制每一层的输出以服从一些约束…

JVM入门篇-JVM的概念与学习路线

JVM入门篇-JVM的概念与学习路线 什么是 JVM 定义 Java Virtual Machine - java 程序的运行环境&#xff08;java 二进制字节码的运行环境&#xff09; 好处 一次编写&#xff0c;到处运行自动内存管理&#xff0c;垃圾回收功能数组下标越界检查多态 比较 jvm jre jdk 常…

C++语法(26)--- 特殊类设计

C语法&#xff08;25&#xff09;--- 异常与智能指针_哈里沃克的博客-CSDN博客https://blog.csdn.net/m0_63488627/article/details/131537799?spm1001.2014.3001.5501 目录 1.特殊类设计 1.设计一个类&#xff0c;不能被拷贝 C98 C11 2.设计一个类&#xff0c;只能在堆上…

Linux学成之路(基础篇0(二十三)MySQL服务(主从MySQL服务和读写分离——补充)

目录 一、MySQL Replication概述 优点 异步复制&#xff08;Asynchronous repication&#xff09; 全同步复制&#xff08;Fully synchronous replication&#xff09; 半同步复制&#xff08;Semisynchronous replication&#xff09; 三、MySQL支持的复制 四、部署主从…

真正帮你实现—MapReduce统计WordCount词频,并将统计结果按出现次数降序排列

项目整体介绍 对类似WordCount案例的词频统计&#xff0c;并将统计结果按出现次数降序排列。 网上有很多帖子&#xff0c;均用的相似方案&#xff0c;重写某某方法然后。。。运行起来可能会报这样那样的错误&#xff0c;这里实现了一种解决方案&#xff0c;分享出来供大家参考…