leetcode刷题3

news2024/9/21 10:23:04

文章目录

  • 前言
  • 回文数
    • 1️⃣ 转成字符串
    • 2️⃣ 求出倒序数再比对
  • 正则表达式匹配[==hard==]
    • 1️⃣ 动态规划
  • 盛最多水的容器
    • 1️⃣ 遍历+分类
    • 2️⃣ 双指针+贪心
  • 最长公共前缀
    • 1️⃣ 遍历(zip+解包)
  • 三数之和
    • 1️⃣ 双指针+递归
  • 最接近的三数之和
    • 1️⃣ 迭代一次+双指针
  • 电话号码的字母组合
    • 1️⃣ 常规方法:暴力循环
    • 2️⃣ 回溯法
  • 合并两个有序链表
    • 1️⃣ 双指针
    • 2️⃣ 递归
  • 总结


前言

    算法小白初入leetcode。本文主要记录个人在leetcode上使用python解题的思路和过程,如果有更好、更巧妙的解题方法,欢迎大家在评论区给出代码或思路。🚀
    C++版可能会作为二刷放在后续的其他文章中。🧐

在这里插入图片描述


回文数

  • 题目描述

在这里插入图片描述

1️⃣ 转成字符串

class Solution:
    def isPalindrome(self, x: int) -> bool:
        y = str(x)
        return y == y[::-1]

在这里插入图片描述

进阶:如果要求不能将整数转为字符串求解:

2️⃣ 求出倒序数再比对

class Solution:
    def isPalindrome(self, x: int) -> bool:
        # 负数肯定不是
        if x < 0:
            return False
        else:
            x_ = x
            y  = 0
            while x > 0:
                x, mod = divmod(x, 10)
                y = y * 10 + mod
            return y == x_                    

在这里插入图片描述

正则表达式匹配[hard]

  • 题目描述

在这里插入图片描述

1️⃣ 动态规划

  • 首先定义状态:令 dp[i][j]表示字符串 s 的前 i 个字符和模式 p 的前 j 个字符是否匹配。
    • dp[i][j] = true 表示 s[0:i] 和 p[0:j] 匹配。
    • dp[i][j] = false 表示 s[0:i] 和 p[0:j] 不匹配。
  • 根据题意写出状态转移方程
  • 基础状态:
    • 当模式 p 和字符串 s 均为空时,dp[0][0] = true
    • 当模式 p 为空而字符串 s 不为空时,dp[i][0] = false(模式无法匹配非空字符串)
    • 当模式 p 不为空而字符串 s 为空时讨论两种情况:1)p=*,则dp[0][j]=dp[0][j-2];2)p!=*,此时的状态肯定是False.
  • 一般状态转移:假设当前遍历到了dp[i][j],有以下情况:
    • p[i]==s[j]或者p[i]=='.',说明p的第i个字符和s的第j个字符可以匹配,状态转移方程为: d p [ i ] [ j ] = d p [ i − 1 ] [ j − 1 ] dp[i][j]=dp[i−1][j−1] dp[i][j]=dp[i1][j1]
    • p[i] == '*',分成两种情况:
      • 如果p[j-1]等于s[i-1]或者p[j-1].,则*匹配0次:dp[i][j] = dp[i][j-2]
      • 否则,*匹配k次,匹配的过程可以这样理解,例如s='abbb',p='ab*',k从1开始递增,这里一共需要递增3次才会匹配成功,需要比较的是s和ab,s和abb,s和abbb;这个过程反映到状态转移过程中实际上是“相反的”,k每递增一次,s就舍弃一个字母,实际上比较的是abbb和p,abb和p,a和p,最后一种情况判断时又变成了*匹配0次的情形,最终只要这几种匹配情况一种匹配上就行,所以这里的转移方程为: d p [ i ] [ j ] = d p [ i ] [ j − 2 ] ∣ d p [ i − 1 ] [ j ] dp[i][j] = dp[i][j-2] \quad | \quad dp[i-1][j] dp[i][j]=dp[i][j2]dp[i1][j]
class Solution:
    def isMatch(self, s: str, p: str) -> bool:
        # 定义 dp[i][j] 表示 s 前i个字符与 p 的前j个字符是否匹配
        dp = [[False] * (len(p) + 1) for _ in range(len(s) + 1)]

        # 初始化
        dp[0][0] = True         # s、p都为空显然是返回True
        for j in range(1, len(p) + 1):  #  当s为空,p不为空时
            if p[j-1] == '*':
                dp[0][j] = dp[0][j - 2]

        # 状态转移
        for i in range(1, len(s)+1):
            for j in range(1, len(p)+1):

                # Case1
                if p[j-1] == s[i-1] or p[j-1]== '.':
                    dp[i][j] = dp[i-1][j-1]

                # Case2
                elif p[j-1] == '*':
                    if s[i-1]!= p[j-2] and p[j-2] != '.':
                        dp[i][j] = dp[i][j-2]
                    
                    else:
                        dp[i][j] = dp[i][j-2] or dp[i-1][j]
        
        return dp[len(s)][len(p)]

在这里插入图片描述

盛最多水的容器

  • 题目描述

在这里插入图片描述

1️⃣ 遍历+分类

  • 很明显可以直接遍历数组中两两组合的数字,即对应容器的两条边长,然后求出对应的储水量即可返回最后的max即可。但是这样做,遍历次数为 n ( n + 1 ) / 2 n(n+1)/2 n(n+1)/2,算法复杂度为 O ( n 2 ) \mathcal{O(n^{2})} O(n2),最后也会超出时间限制。
  • 不过想一想又会发现:在考虑1这个数字的所有可能情况时 [ ( 1 , 8 ) , ( 1 , 6 ) , ( 1 , 2 ) , . . . ( 1 , 7 ) ] [(1,8),(1,6),(1,2),...(1,7)] [(1,8),(1,6),(1,2),...(1,7)],因为 7 > 1 7>1 7>1,所以这些组合中得到的最大面积就是 ( 1 , 7 ) (1,7) (1,7)这种情况,因为最终的面积是高度×宽度,而高度是由最短的那条边决定的,而此时的宽度就是最大的,高度最大值也就是 1 1 1。也就是说对于考虑每个数字的所有可能情况时,从右侧往左侧遍历,如果遍历到一个比该数字还要大或等于该数字的,那么剩下的就不用考虑了。
  • 那如果是在考虑 8 8 8这个数字的所有情况呢 [ ( 8 , 6 ) , ( 8 , 2 ) , ( 8 , 5 ) , . . . ( 8 , 7 ) ] [(8,6),(8,2),(8,5),...(8,7)] [(8,6),(8,2),(8,5),...(8,7)],由于 7 < 8 7<8 7<8,此时可能会存在一个组合得到的面积比现在的面积还要大,需要继续遍历,一直到一个大于等于 8 8 8这个数字。
  • 结合上面思路,代码如下:
class Solution:
    def maxArea(self, height: List[int]) -> int:
        left = 0
        right = len(height) - 1
        re = 0
        while left < right:
            re = max(re,min(height[left],height[right])* (right - left))
            
            if height[left]*(right-left) <= re:   # 当左侧数字可能存在的最大面积都小于当前的最大面积时,直接继续下一个循环
                left += 1
                continue
            if height[right] >= height[left]:  # 右侧指针的数字比左侧大时,考虑下一个数字的情况
                left += 1
                right = len(height) - 1
                continue
            else:							# 右侧指针的数字较小时,向左移动右指针
                right -= 1
        return re

在这里插入图片描述
效率并不高🐢

2️⃣ 双指针+贪心

  • 第一种方法是从遍历所有组合的角度出发的,如果从最大面积的角度出发可以发现,同样双指针从首尾开始移动,哪一侧的数字小,就移动哪侧的指针,因为面积是由短边决定的,如果移动数字大的那一侧指针,高度不会变化,宽度必定减少。考虑到指针是逐步向中心收缩的,意味着宽度是在逐步减少的,所以如果整个数组中的最大值×当前的宽度小于当前得到的最大面积时,可以直接返回得到的最大面积,代码如下:
class Solution:
    def maxArea(self, height: List[int]) -> int:
        left  = 0
        right = len(height)-1
        res = 0
        maximun = max(height)
        while left < right:
            
            area = min(height[left], height[right]) * (right - left)
            res = max(res, area)

            if (right-left)*maximun <= res:  # 当前情况下存在的可能最大面积如果都小于当前得到的最大值,那么后续就不用考虑了,因为宽度在减少,面积一定会减少
                break

            if height[left] < height[right]:
                left += 1
            else:
                right -= 1
        return res

在这里插入图片描述
快起来了🚀

最长公共前缀

  • 题目描述:

在这里插入图片描述

1️⃣ 遍历(zip+解包)

  • python做的话比较简单,直接取出对应位置的字符判断是否一致即可。
class Solution:
    def longestCommonPrefix(self, strs: List[str]) -> str:
        min_length = min(list(map(lambda x:len(x),strs)))
        res = ''
        for i in zip(*strs):
            if len(set(i)) != 1:
                res += i[0]
            else:
                break
        return res

在这里插入图片描述

三数之和

  • 题目描述:

在这里插入图片描述

1️⃣ 双指针+递归

  • 思路:
    • 1、 排序:确保输入数组是排序的。如果未排序,则首先对其进行排序。
    • 2、初始化指针:设置两个指针,左指针lo初始化为 start 位置,右指针 hi 初始化为数组的最后一个元素位置(sz - 1)。
    • 3、计算当前和:计算 nums[lo]nums[hi] 的和,记为 s
    • 4、比较和与目标值
      • 如果 s小于目标值 target,说明需要增大 s,因此移动左指针 lo 向右。
      • 如果 s大于目标值 target,说明需要减小 s,因此移动右指针 hi 向左。
      • 如果 s等于目标值 target,说明找到一个符合条件的二元组,将其加入结果列表中,然后分别移动左指针 lo 和右指针 hi,以避免重复元素。
class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        nums.sort()                                   # 对输入的列表进行排序
        return self.nSumTarget(nums, 3, 0, 0)         # 这是一个通用的函数,用于找到 n 个数的和等于目标值

    def remove_duplicate_lists(self , lists: List[List[int]]) -> List[List[int]]:
        unique_lists = set(tuple(sorted(sublist)) for sublist in lists)        # 将子列表排序,并转化为元组,利用集合去重
        return [list(sublist) for sublist in unique_lists]                     # 将去重后的元组转回列表


    def nSumTarget(self, nums: List[int], n: int, start: int, target: int) -> List[List[int]]:

        '''
        nums  : 排序后的数字列表
        n     : 我们希望找到几个数的和
        start : 列表中开始计算的起始索引
        target: 我们希望凑出的目标和
        '''
        sz = len(nums)
        res = []

        # 如果找到的数字个数少于 2 或者 列表长度小于 n,则返回空结果
        if n < 2 or sz < n:
            return res

        # 两数之和是基本情况
        if n == 2:
            # 使用双指针
            lo, hi = start, sz - 1
            while lo < hi:
                s = nums[lo] + nums[hi]
                left, right = nums[lo], nums[hi]
                if s < target:
                    # 如果和小于目标值,移动左指针增大s
                    while lo < hi and nums[lo] == left:
                        lo += 1
                elif s > target:
                    # 如果和大于目标值,移动右指针减小s
                    while lo < hi and nums[hi] == right:
                        hi -= 1
                else:
                    # 如果和等于目标值,找到一个解,将其加入结果中
                    res.append([left, right])
                    while lo < hi and nums[lo] == left:         # 移动左指针以避免重复
                        lo += 1
                    while lo < hi and nums[hi] == right:        # 移动右指针以避免重复
                        hi -= 1
        else:
            # 当 n > 2 时,递归计算 (n-1)Sum 的结果
            for i in range(start, sz):
                # 递归调用,寻找 (n-1)Sum 的解
                sub = self.nSumTarget(nums, n - 1, i + 1, target - nums[i])
                for arr in sub:
                    # 将 nums[i] 加入 (n-1)Sum 的结果中,得到 nSum 的解
                    arr.append(nums[i])
                    res.append(arr)
                # 跳过重复的元素,以避免重复解
                while i < sz - 1 and nums[i] == nums[i + 1]:
                    i += 1
        return self.remove_duplicate_lists(res)

在这里插入图片描述

最接近的三数之和

  • 题目描述

在这里插入图片描述

1️⃣ 迭代一次+双指针

  • 思路和三数之和的思路一致,这类问题都可以用这种方法通解。直接看代码:
class Solution:
    def threeSumClosest(self, nums: List[int], target: int) -> int:
        # 循环 + 双指针
        if len(nums) < 3:
            return None
        
        # 首先排序
        nums.sort()
        difference = float('inf')  # 最接近的值和目标值之间的差值

        for i in range(len(nums) - 2):
            # 当其中一个数为nums[i]时,找出最接近的三数之和,此时通过另一个函数找出最接近的两数之和
            sum = nums[i] + self.twoSumClosest(nums[i+1:], target - nums[i])

            if abs(target - sum) < abs(difference):
                difference = target - sum
        return target - difference
    
    def twoSumClosest(self, num, target):
        left, right = 0, len(num) -1
        difference = float('inf')
        while left < right:
            sum = num[left] + num[right]
            if abs(target - sum) < abs(difference):
                difference = target - sum
            if sum < target:
                left += 1
            else:
                right -=1
        return target - difference

在这里插入图片描述

电话号码的字母组合

1️⃣ 常规方法:暴力循环

  • 常规方法非常好理解:每次取出一个数字,该数字对应的所有字母与之前的结果进行组合,直到遍历所有数字即可。
class Solution:
    def letterCombinations(self, digits: str) -> List[str]:
        num_to_char = {
            "2": ['a', 'b', 'c'], "3": ['d', 'e', 'f'], "4":['g', 'h', 'i'] , 
            "5": ['j', 'k', 'l'], "6": ['m', 'n', 'o'], "7":['p', 'q', 'r', 's'] , 
            "8": ['t', 'u', 'v'], "9": ['w', 'x', 'y', 'z']}
        res = []
        res = ['']
        while digits:
            
            cur_res = num_to_char[digits[-1]]
            res     = list(map(lambda x: x[0] + x[1], [(i, j) for i in cur_res for j in res]))
            digits  = digits[:-1]

        if res == ['']:
            res = []
        return res 

在这里插入图片描述

2️⃣ 回溯法

  • 内容参考:回溯算法解题套路框架
  • 回溯算法都是在遍历一棵树,树的叶子节点对应着其中一个解。
    • 输入的第一个数字开始,依次遍历每个字母。
    • 对于每个字母,进入下一层递归处理下一个数字。
    • 如果已经处理完所有的数字(递归到底),说明已经生成了一个有效的字母组合,记录下
      来。

代码:

class Solution:
    
    def __init__(self):
        self.result = []  # 保存结果,即存储所有字母组合

    def letterCombinations(self, digits: str) -> List[str]:
        num_to_char = {
        "2": ['a', 'b', 'c'], "3": ['d', 'e', 'f'], "4":['g', 'h', 'i'], 
        "5": ['j', 'k', 'l'], "6": ['m', 'n', 'o'], "7":['p', 'q', 'r', 's'] , 
        "8": ['t', 'u', 'v'], "9": ['w', 'x', 'y', 'z']}
        
        def backtrack(index, path):
            # 确定结束条件
            if index == len(digits):
                self.result.append(''.join(path))
                return
            # 当前数字对应的所有字母
            current_chars = num_to_char[digits[index]]

            for char in current_chars:
                # 做选择
                path.append(char)

                # 递归处理下一个数字
                backtrack(index + 1, path)

                # 撤销选择
                path.pop()

        if not digits:
            return []
        backtrack(index=0, path=[])  # 从第一个数字开始,路径初始化为空
        return self.result

在这里插入图片描述

合并两个有序链表

  • 题目描述

在这里插入图片描述

1️⃣ 双指针

  • 两个指针从各自链表的头结点开始移动,比较对应的值,将更小的数放到新链表中即可,一直到两个链表中元素都遍历完。
  • 在链表中如果涉及到新链表时,可以使用虚拟头结点这个技巧。
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
        head = ListNode(-1)  # 虚拟头结点
        ptr  = head
        ptr1 = list1
        ptr2 = list2

        while ptr1  and ptr2 :
            # 比较两个指针的值,选择较小的值添加到新链表
            if ptr1.val < ptr2.val:
                ptr.next = ptr1
                ptr1     = ptr1.next
            else:
                ptr.next = ptr2
                ptr2     = ptr2.next
                
            ptr = ptr.next

        if ptr1:
            ptr.next = ptr1
        if ptr2:
            ptr.next = ptr2

        return head.next

在这里插入图片描述

2️⃣ 递归

  • 这一题递归理解写起来并不算难:比较两个节点值的大小,如果list1<list2,就把list1下一个节点和list2放到这个函数中进行递归;反之,就把list2下一个节点和list1放到这个函数中进行递归,代码如下:
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
        
        if not list1:
            return list2
        if not list2:
            return list1

        if list1.val < list2.val:
            list1.next = self.mergeTwoLists(list1.next, list2)
            return list1
        else:
            list2.next = self.mergeTwoLists(list1, list2.next)
            return list2    

在这里插入图片描述

总结

算法小白初入leetcode,期待给出更精妙的算法🚀🚀🚀

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

携手阿里云CEN:共创SD-WAN融合广域网

在9月19日举行的阿里云云栖大会上&#xff0c;犀思云作为SD-WAN领域的杰出代表及阿里云的SD-WAN重要合作伙伴&#xff0c;携手阿里云共同推出了创新的企业上云方案——Fusion WAN智连阿里云解决方案。这一创新方案不仅彰显了犀思云在SD-WAN技术领域的深厚积累&#xff0c;更体现…

前端web端项目运行的时候没有ip访问地址

我们发现 没有netWork 的地址 导致 团队内其他同学无法打开我们的地址 进行访问 在page.json 中的运行 指令中 添加 --host 记得加上空格 这样我们就可以看到这个地址了 团队其他同学 就可以访问我们这个地址了

Resnet50网络——口腔癌病变识别

一 数据准备 1.导入数据 import matplotlib.pyplot as plt import tensorflow as tf import warnings as w w.filterwarnings(ignore) # 支持中文 plt.rcParams[font.sans-serif] [SimHei] # 用来正常显示中文标签 plt.rcParams[axes.unicode_minus] False # 用来正常显示负…

2024华为杯研究生数学建模竞赛(研赛)选题建议+初步分析

难度&#xff1a;DE<C<F&#xff0c;开放度&#xff1a;CDE>F。 华为专项的题目&#xff08;A、B题&#xff09;暂不进行选题分析&#xff0c;不太建议大多数同学选择&#xff0c;对自己专业技能有很大自信的可以选择华为专项的题目。后续会直接更新A、B题思路&#…

计算机网络传输层---课后综合题

线路&#xff1a;TCP报文下放到物理层传输。 TCP报文段中&#xff0c;“序号”长度为32bit&#xff0c;为了让序列号不会循环&#xff0c;则最多能传输2^32B的数据&#xff0c;则最多能传输&#xff1a;2^32/1500B个报文 结果&#xff1a; 吞吐率一个周期内传输的数据/周期时间…

2024/9/19、20 数学20题

极大线性无关组&#xff1a;

基于C#+SQL Server2005(WinForm)图书管理系统

图书管理系统 一、 首先把数据库脚本贴出来(数据库名为library) USE [library] GO /****** Object: Table [dbo].[books] Script Date: 06/12/2016 11:27:12 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[books]([bNum] [nvarchar](10…

Arthas sysprop(查看和修改JVM的系统属性)

文章目录 二、命令列表2.1 jvm相关命令2.1.4 sysprop&#xff08;查看和修改JVM的系统属性&#xff09;举例1&#xff1a;sysprop 查看所有系统属性举例2&#xff1a;sysprop java.version 查看单个属性&#xff0c;支持通过tab补全 二、命令列表 2.1 jvm相关命令 2.1.4 sysp…

STL-常用算法 遍历/查找/排序/拷贝和替换/算数生成/集合算法

STL常用算法 常用的遍历算法 for_each #define _CRT_SECURE_NO_WARNINGS #include<iostream> using namespace std; #include<vector> #include<algorithm>void myPrint(int v) {cout << v << " "; }class MyPrint { public:void op…

React学习笔记(三)——React 组件通讯

1. 组件通讯-概念 了解组件通讯的意义 大致步骤&#xff1a; 知道组件的特点知道组件通讯意义 具体内容&#xff1a; 组件的特点 组件是独立且封闭的单元&#xff0c;默认情况下&#xff0c;只能使用组件自己的数据在组件化过程中&#xff0c;通常会将一个完整的功能拆分成多…

cesium.js 入门到精通(5-2)

在cesium 的配置中 有一些参数 可以配置地图的显示 显示出 水的动态显示 山的效果 相当于一些动画显示的效果 var viewer new Cesium.Viewer("cesiumContainer", {infoBox: false,terrainProvider: await Cesium.createWorldTerrainAsync({requestWaterMask: tru…

【计算机网络】计算机网络基础二

&#x1f351;个人主页&#xff1a;Jupiter. &#x1f680; 所属专栏&#xff1a;Linux从入门到进阶 欢迎大家点赞收藏评论&#x1f60a; 目录 以太网的通信原理令牌环网的通信原理网络传输基本流程 数据包封装和分用 网络传输流程图 局域网通信&#xff08;同一个网段内的两台…

PY+MySQL(等先完成mysql的学习)

第一章&#xff1a;准备工作&#xff08;重点关于mysql&#xff09; win安装 下载&#xff1a; 网址&#xff1a;MySQL :: Download MySQL Community Server版本&#xff1a;我的是8.0&#xff0c;但是建议5.7 下载&#xff1a;安装&#xff0c;因为是zip文件所以直接解压就好了…

股价预测,非线性注意力更佳?

作者:老余捞鱼 原创不易,转载请标明出处及原作者。 写在前面的话: 本文探讨了在 transformer 模型中使用非线性注意力来预测股票价格的概念。我们讨论了黎曼空间和希尔伯特空间等非线性空间的数学基础,解释了为什么非线性建模可能是有利的,并提供了在代码中实现这种…

MySQL 主从复制部署与优化

文章目录 前言 在现代数据库管理中&#xff0c;MySQL 主从复制是一种关键技术&#xff0c;用于提高数据的可用性和性能。随着 Docker 容器技术的普及&#xff0c;利用 Docker 搭建 MySQL 主从复制环境已成为一种趋势&#xff0c;它提供了一种简便、高效且可扩展的解决方案。本…

828华为云征文|Flexus X实例Docker+Jenkins+gitee实现CI/CD自动化部署-解放你的双手~

目录 前言 实验步骤 环境准备 安装Portainer 拉取镜像 更换镜像源 启动容器 安装jenkins 拉取镜像 获取管理员密码 新建流水线项目 Portainer配置 gitee配置WebHooks 构建 修改代码&#xff0c;自动部署 前言 &#x1f680; 828 B2B企业节特惠来袭&#xff0c;…

Hadoop 常用生态组件

Hadoop核心组件 安装 Hadoop 时&#xff0c;通常会自动包含以下几个关键核心组件&#xff0c;特别是如果使用了完整的 Hadoop 发行版&#xff08;如 Apache Hadoop、Cloudera 或 Hortonworks 等&#xff09;。这些组件构成了 Hadoop 的核心&#xff1a; 1. HDFS&#xff08;H…

数据篇| 关于Selenium反爬杂谈

友情提示:本章节只做相关技术讨论, 爬虫触犯法律责任与作者无关。 LLM虽然如火如荼进行着, 但是没有数据支撑, 都是纸上谈兵, 人工智能的三辆马车:算法-数据-算力,缺一不可。之前写过关于LLM微调文章《微调入门篇:大模型微调的理论学习》、《微调实操一: 增量预训练(Pretrai…

选择五金车床精密加工厂的五大要点

在五金制造行业&#xff0c;五金车床精密加工是生产高品质零部件的关键环节。随着市场需求的日益多样化和对产品质量要求的不断提高&#xff0c;选择一家合适的五金车床精密加工厂变得至关重要。然而&#xff0c;面对众多的加工厂&#xff0c;如何做出正确的选择却是一个难题。…

光耦知识分享 | 晶体管光耦与可控硅光耦的区别

晶体管光耦和可控硅光耦是两种常见的光电耦合器件&#xff0c;它们在电子电路中扮演着重要的角色。下面将介绍晶体管光耦和可控硅光耦的区别以及它们的主要应用。 结构区别 晶体管光耦通常由一个发光二极管&#xff08;LED&#xff09;和一个光敏晶体管&#xff08;光控晶体管…