【CodeTop】TOP 100 刷题 31-40

news2025/7/13 1:36:49

文章目录

  • 31. 二叉树中的最大路径和
    • 题目描述
    • 代码与解题思路
  • 32. 合并区间
    • 题目描述
    • 代码与解题思路
  • 33. 编辑距离
    • 题目描述
    • 代码与解题思路
  • 34. 二叉树的中序遍历
    • 题目描述
    • 代码与解题思路
  • 35. 最长公共子序列
    • 题目描述
    • 代码与解题思路
  • 36. 二分查找
    • 题目描述
    • 代码与解题思路
  • 37. 二叉树的右视图
    • 题目描述
    • 代码与解题思路
  • 38. 用栈实现队列
    • 题目描述
    • 代码与解题思路
  • 39. 删除排序链表中的重复元素 II
    • 题目描述
    • 代码与解题思路
  • 40. 寻找两个正序数组的中位数
    • 题目描述
    • 代码与解题思路

31. 二叉树中的最大路径和

题目链接:124. 二叉树中的最大路径和

题目描述

代码与解题思路

func maxPathSum(root *TreeNode) int {
    ans := math.MinInt
    var dfs func(*TreeNode) int
    dfs = func(node *TreeNode) int {
        if node == nil {
            return 0
        }
        left := dfs(node.Left)
        right := dfs(node.Right)
        ans = max(ans, left+right+node.Val)
        return max(node.Val+max(left, right), 0)
    }
    dfs(root)
    return ans
}

树形 DP,推荐学习:https://www.bilibili.com/video/BV17o4y187h1/

32. 合并区间

题目链接:56. 合并区间

题目描述

代码与解题思路

func merge(intervals [][]int) [][]int {
    sort.Slice(intervals, func(i, j int) bool {
        return intervals[i][0] < intervals[j][0]
    })
    res := [][]int{}
    pre := intervals[0]
    for i := 1; i < len(intervals); i++ {
        cur := intervals[i]
        if pre[1] < cur[0] { // 区间不重合了, 追加到 res 数组
            res = append(res, pre)
            pre = cur
        } else { // 区间重合, 扩大区间范围
            pre[1] = max(cur[1], pre[1])
        }
    }
    res = append(res, pre) // 剩下最后一个没法合并的区间, 直接追加
    return res
}

画图模拟即可,顺便学习一下如何排序二维数组:

sort.Slice(intervals, func(i, j int) bool {
    return intervals[i][0] < intervals[j][0]
})

33. 编辑距离

题目链接:72. 编辑距离

题目描述

代码与解题思路

func minDistance(word1 string, word2 string) int {
    n, m := len(word1), len(word2)
    // 创建 dp 数组
    dp := make([][]int, n+1)
    for i := 0; i < len(dp); i++ {
        dp[i] = make([]int, m+1)
    }
    // 初始化
    for i := 0; i <= n; i++ {
        dp[i][0] = i
    }
    for i := 0; i <= m; i++ {
        dp[0][i] = i
    }
    // 填表
    for i, v1 := range word1 {
        for j, v2 := range word2 {
            if v1 == v2 {
                dp[i+1][j+1] = dp[i][j]
            } else {
                dp[i+1][j+1] = min(min(dp[i+1][j], dp[i][j+1]), dp[i][j])+1
            }
        }
    }
    return dp[n][m]
}

dp 问题的核心就是状态转移方程的推导,通过分类讨论题目要求,我们能得出有这几种情况:

  1. 两个字母相同,不需要修改 dp[ i+1 ][ j+1 ] = dp[ i ][ j ]
  2. 两个字母不同分三种情况:
    1. word1 缺失,只需要进行一个删除操作即可 dp[ i+1 ][ j ] + 1
    2. word2 缺失,只需要进行一个删除操作即可 dp[ i ][ j+1 ] + 1
    3. word1 和 word2 字母不相同,进行替换操作即可 dp[ i+1 ][ j+1 ] + 1

最后取第二种情况的最小值即可,因为要求最少的操作次数

最后就是初始化 dp 数组,从左往右,从上往下按顺序填表

省流:熟练的默写动态规划的套路罢了,到底懂没懂不好说

34. 二叉树的中序遍历

题目链接:94. 二叉树的中序遍历

题目描述

代码与解题思路

先来个递归解法:

func inorderTraversal(root *TreeNode) (ans []int) {
    var inorder func(*TreeNode)
    inorder = func(root *TreeNode) {
        if root == nil {
            return
        }
        inorder(root.Left)
        ans = append(ans, root.Val)
        inorder(root.Right)
    }
    inorder(root)
    return ans
}

非递归:

// 记住中序遍历顺序:左根右
func inorderTraversal(root *TreeNode) (ans []int) {
    st := list.New()
    cur := root
    for cur != nil || st.Len() > 0 {
        if cur != nil { // 找最左节点
            st.PushBack(cur)
            cur = cur.Left
        } else { // 栈顶是最左节点了
            cur = st.Remove(st.Back()).(*TreeNode)
            ans = append(ans, cur.Val) // 取值
            cur = cur.Right // 找右
        }
    }
    return ans
}

我们来根据代码梳理一下他的流程

  1. 将当前节点入栈,然后一直往左遍历直到走到 nil
  2. 走到 nil 之后,上一个节点,也就是栈顶的元素就是最左节点,输出到 ans然后往右遍历一步,持续这个三步循环

这三步模拟的就是 “左根右” 的遍历方式,刚好也是三步,找到最左,取根,找右,循环往复,就能完成中序遍历了。

迭代算法确实不太好想,但是上手模拟一遍还是比较好理解的。

35. 最长公共子序列

题目链接:1143. 最长公共子序列

题目描述

代码与解题思路

func longestCommonSubsequence(text1 string, text2 string) int {
    n, m := len(text1), len(text2)
    dp := make([][]int, n+1)
    for i := 0; i < n+1; i++ {
        dp[i] = make([]int, m+1)
    }
    for i, v1 := range text1 {
        for j, v2 := range text2 {
            if v1 == v2 {
                dp[i+1][j+1] = dp[i][j] + 1
            } else {
                dp[i+1][j+1] = max(dp[i+1][j], dp[i][j+1])
            }
        }
    }
    return dp[n][m]
}

这道题需要注意的是,子序列和子数组,子数组必须是连续的,而子序列不一定。所以子序列相关的题目是经典的动态规划类型题目,所以我们首先分析题目然后写出状态转移方程:

  1. 如果两个字母相同,dp[ i+1 ][ j+1 ] = dp[ i ][ j ] + 1
  2. 如果两个字母不相同,看看之前有没有出现过相同的子序列,继承一下最长子序列的长度:dp[ i+1 ][ j+1 ] = max(dp[ i+1 ][ j ], dp[ i ][ j+1 ])

看图:

接着就是愉快的默写,初始化 dp 数组,填表,返回。

36. 二分查找

题目链接:704. 二分查找

题目描述

代码与解题思路

func search(nums []int, target int) int {
    left, right := 0, len(nums)-1
    for left <= right {
        mid := left+(right-left)/2
        if nums[mid] < target {
            left = mid+1
        } else if nums[mid] > target {
            right = mid-1
        } else {
            return mid
        }
    }
    return -1
}

经典二分,熟练二分的思想,思考和控制好二分的边界,那二分用起来就不困难。

37. 二叉树的右视图

题目链接:199. 二叉树的右视图

题目描述

代码与解题思路

func rightSideView(root *TreeNode) (ans []int) {
    if root == nil {
        return nil
    }
    Queue := []*TreeNode{root}
    for len(Queue) > 0 {
        n := len(Queue)
        nextQueue := []*TreeNode{}
        for n > 0 {
            cur := Queue[0]
            Queue = Queue[1:]
            if cur.Left != nil {
                nextQueue = append(nextQueue, cur.Left)
            }
            if cur.Right != nil {
                nextQueue = append(nextQueue, cur.Right)
            }
            n--
            if n == 0 {
                ans = append(ans, cur.Val)
            }
        }
        Queue = nextQueue
    }
    return ans
}

今天真是头昏了,被层序玩傻了,下次写层序遍历用土方法吧,先画图,然后对照着图的思路来写层序遍历,不要浪了,踏踏实实才是真本领,再怎么背模板总会忘记的,融会贯通才是最重要的。

38. 用栈实现队列

题目链接:232. 用栈实现队列

题目描述

代码与解题思路

type MyQueue struct {
    st1 []int
    st2 []int
}

func Constructor() MyQueue {
    return MyQueue{
        st1: []int{},
        st2: []int{},
    }
}

func (q *MyQueue) Push(x int)  {
    q.st1 = append(q.st1, x)
}

func (q *MyQueue) Pop() int {
    st1ToSt2(q)
    front := q.st2[len(q.st2)-1]
    q.st2 = q.st2[:len(q.st2)-1]
    return front
}

func (q *MyQueue) Peek() int {
    st1ToSt2(q)
    return q.st2[len(q.st2)-1]
}

func st1ToSt2(q *MyQueue) { // 抽象出数据流转操作
    if len(q.st2) == 0 {
        n := len(q.st1) // 注意, 因为后续操作会影响到 q.st1
        for i := 0; i < n; i++ {
            q.st2 = append(q.st2, q.st1[len(q.st1)-1]) 
            q.st1 = q.st1[:len(q.st1)-1]
        }
    }
}

func (q *MyQueue) Empty() bool {
    if len(q.st1) == 0 && len(q.st2) == 0 {
        return true
    }
    return false
}

这里有个需要注意的地方,就是在遍历的时候会改变 q.st1 数组的大小,所以在使用 for 循环的时候需要提前求出 n := len(q.st1) 然后使用 n,而不能直接使用 len(q.st1) 作为判断的条件

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

题目链接:82. 删除排序链表中的重复元素 II

题目描述

代码与解题思路

func deleteDuplicates(head *ListNode) *ListNode {
    phead := &ListNode{Next: head}
    cur := phead // cur 一直保持在前一个节点这个相对位置
    for cur.Next != nil && cur.Next.Next != nil {
        nVal, nnVal := cur.Next.Val, cur.Next.Next.Val
        if nnVal == nVal { // 如果出现相同的情况, 就跳过重复节点
            for cur.Next != nil && cur.Next.Val == nVal {
                cur.Next = cur.Next.Next
            }
        } else {
            cur = cur.Next
        }
    }
    return phead.Next
}

这个是练习链表的基本功问题,下次遇到再重新做做,检测一下自己的链表内功。

40. 寻找两个正序数组的中位数

题目链接:4. 寻找两个正序数组的中位数

题目描述

代码与解题思路

func findMedianSortedArrays(nums1 []int, nums2 []int) float64 {
    nums1 = append(nums1, nums2...)
    sort.Ints(nums1)
    if len(nums1)%2!=0 {
        return float64(nums1[len(nums1)/2])
    }
    return float64(nums1[len(nums1)/2-1]+nums1[len(nums1)/2])/2
}

这道题比较难,所以我决定开摆,直接合并数组+排序一气呵成。

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

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

相关文章

STM32F407-14.3.13-01发生外部事件时清除 OCxREF 信号

发生外部事件时清除 OCxREF 信号 对于给定通道&#xff0c;在 ETRF⑧ 输入施加高电平&#xff08;相应 TIMx_CCMRx 寄存器中的 OCxCE⑦ 使能位置“1”&#xff09;&#xff0c;可使 OCxREF⑨ 信号变为低电平。OCxREF⑨ 信号将保持低电平&#xff0c;直到发生下一更新事件 (UEV)…

SAM+使用SAM应用数据集完成分割

什么是SAM&#xff1f; SAM(Segment Anything Model&#xff09;是由 Meta 的研究人员团队创建和训练的深度学习模型。在 Segment everything 研究论文中&#xff0c;SAM 被称为“基础模型”。 基础模型是在大量数据上训练的机器学习模型&#xff08;通常通过自监督或半监督学习…

农业杀虫剂市场分析:我国实现销售收入319.3亿元

农业杀虫剂&#xff0c;指的是农业用的杀虫化学制剂。主要用于防治农业害虫和城市卫生害虫的药品&#xff0c;使用历史长远、用量大、品种多。 按毒理作用可分为&#xff1a;①神经毒剂。作用于害虫的神经系统&#xff0c;如滴滴涕、对硫磷、呋喃丹、除虫菊酯等。②呼吸毒剂。抑…

ssm党务政务服务热线平台源码和论文答辩PPT

摘要 首先,论文一开始便是清楚的论述了系统的研究内容。其次,剖析系统需求分析,弄明白“做什么”,分析包括业务分析和业务流程的分析以及用例分析,更进一步明确系统的需求。然后在明白了系统的需求基础上需要进一步地设计系统,主要包罗软件架构模式、整体功能模块、数据库设计…

易点易动设备管理系统--提升设备能耗管理效率的工具

在当今的节能环保意识日益增强的社会背景下&#xff0c;设备能耗管理成为了市场推广人员关注的焦点之一。为了帮助市场推广人员提升设备能耗管理效率&#xff0c;易点易动设备管理系统应运而生。本文将详细介绍易点易动设备管理系统的功能和优势&#xff0c;以及如何借助该系统…

class050 双指针技巧与相关题目【算法】

class050 双指针技巧与相关题目【算法】 算法讲解050【必备】双指针技巧与相关题目 code1 922. 按奇偶排序数组 II // 按奇偶排序数组II // 给定一个非负整数数组 nums。nums 中一半整数是奇数 &#xff0c;一半整数是偶数 // 对数组进行排序&#xff0c;以便当 nums[i] 为…

springboot项目中注入bean后,调用时报n

需求&#xff1a; 在socket接收到上报数据后&#xff0c;在handler中调用工具类中ProtocolAnalyse的conAnalyse(byte[] data, int dataLen)解析数据。解析数据后&#xff0c;将解析后的结果保存至数据库。注入了三个bean&#xff1a; Autowiredprivate PersonTeService person…

8个Python高效数据分析的技巧!

一行代码定义List 定义某种列表时&#xff0c;写For 循环过于麻烦&#xff0c;幸运的是&#xff0c;Python有一种内置的方法可以在一行代码中解决这个问题。下面是使用For循环创建列表和用一行代码创建列表的对比。 x [1,2,3,4] out [] for item in x:out.append(item**2) …

通付盾连续九年荣登《中国网络安全企业100强》榜单,再次彰显创新与实力!

2023年12月1日&#xff0c;由中国计算机学会抗恶劣环境计算机专业委员会、信息产业信息安全测评中心、安全牛联合发起的第十一版《中国网络安全企业100强》正式发布。通付盾凭借强大的创新技术和优质的服务能力&#xff0c;再度入选百强榜单。此为自2015年起&#xff0c;通付盾…

YOLOv5改进: RT-DETR引入YOLOv5,neck和检测头助力检测

💡💡💡本文独家改进: 1) RT-DETR neck代替YOLOv5 neck部分; 2)引入RTDETRDecoder 多个订阅者要求(多个订阅者有需求会在专栏里进行更新),想出一期RT-DETR的neck引入到YOLOv5,那就安排 💡💡💡Yolov5/Yolov7魔术师,独家首发创新(原创),适用于Yolov5、Yo…

C++ 操作MinIO做文件数据的上传和下载(踩坑与经验)包含编译包

前言 最近在做项目流程优化&#xff0c;准备将之前的java对文件的操作转换到c端&#xff0c;因此做了基于c的minio操作的测试demo。期间的各种踩坑与问题&#xff0c;花了一天时间总算是成功了&#xff0c;当然还有一些小问题&#xff0c;等待后续其他大拿解决。 项目环境 v…

【Android】Glide的简单使用(上)

文章目录 引入Glide的优点:缺点: 使用常用方法:从网络加载图片从文件加载图片加载resource资源加载URI地址设置占位图出错时的图片占位图图片过渡的Transitions自定义过渡动画图片大小调整缩放图片播放gifasGif()把Gif当作Bitmap播放显示本地视频缩略图 引入 Glide是Google员工…

ISNAS-DIP: Image-Specific Neural Architecture Search for Deep Image Prior

ISNAS-DIP&#xff1a;用于深度图像先验的图像特定神经架构搜索 论文链接&#xff1a;https://arxiv.org/abs/2111.15362v2 项目链接&#xff1a;https://github.com/ozgurkara99/ISNAS-DIP Abstract 最近的研究表明&#xff0c;卷积神经网络(CNN)架构在频谱上偏向较低频率&…

装修风格及要求

水电改造 报价&#xff1f; 电线 3C认证国标BV线&#xff08;非BVR&#xff09;&#xff0c;电线上有厂名&#xff0c;买足百米的 厨卫空调4平方线普通插座2.5平方线冰箱2.5平方线照明2.5平方线入户主线6平方或10平方 地面电线点对点&#xff0c;线和线管连接处要有锁扣 品…

Pandas使用过程中的神器加持 你不用不要怪我

Pandas是我们日常处理表格数据最常用的包&#xff0c;但是对于数据分析来说&#xff0c;Pandas的DataFrame还不够直观&#xff0c;所以今天我们将介绍4个和Pandas相关的Python包&#xff0c;可以将Pandas的DataFrame转换交互式表格&#xff0c;让我们可以直接在上面进行数据分析…

将文件夹中所有文件名取出

dir C:\Users\是啊\Desktop\实验五/b>C:\Users\是啊\Desktop\1111.xls C:\Users\是啊\Desktop\实验五&#xff08;这个是文件夹路径&#xff09; /b &#xff08;参数&#xff09; C:\Users\是啊\Desktop\1111.xls&#xff08;文件名输出的文件路径&#xff09;

电路装修干货上篇|装修小白硬装必做功课。福州中宅装饰,福州装修

你是否曾经遇到过这样的情况&#xff1a;同时开启浴霸和电磁炉时&#xff0c;家里的电闸却跳了。这种情况往往会让人们对家居装修中的电线布置产生疑问。今天&#xff0c;以一位从业装修工作10年的工长的经验&#xff0c;为大家解答有关电线布置的常见问题。 1️⃣电线的平方数…

★581. 最短无序连续子数组

581. 最短无序连续子数组 方法一&#xff1a; class Solution {public int findUnsortedSubarray(int[] nums) {// 数组的复制int[] sortednums new int[nums.length];System.arraycopy(nums, 0, sortednums, 0, nums.length);Arrays.sort(sortednums);int l0,rnums.length-1;…

基于Java SSM框架实现汽车在线销售系统项目【项目源码+论文说明】计算机毕业设计

基于java的SSM框架实现汽车在线销售系统演示 摘要 21世纪的今天&#xff0c;随着社会的不断发展与进步&#xff0c;人们对于信息科学化的认识&#xff0c;已由低层次向高层次发展&#xff0c;由原来的感性认识向理性认识提高&#xff0c;管理工作的重要性已逐渐被人们所认识&a…

Leetcode—383.赎金信【简单】

2023每日刷题&#xff08;五十&#xff09; Leetcode—383.赎金信 实现代码 class Solution { public:int arr[26] {0};int arr2[26] {0};bool canConstruct(string ransomNote, string magazine) {int len ransomNote.size();int len2 magazine.size();for(int i 0; i …