当前位置: 首页 > article >正文

LeetCode 第22~24题

目录

LeetCode 第22题: 括号生成

LeetCode 第23题:合并k个升序链表

LeetCode 第24题:两两交换链表中的节点

LeetCode 第22题: 括号生成

题目描述

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

难度:中等
题目链接:22. 括号生成 - 力扣(LeetCode)

示例1:

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

 示例2:
 

输入:n = 1
输出:["()"]

提示:1<=n<=8

解题思路:
回溯法

  • 使用StringBuilder构建当前括号组合
  • 记录已使用的左括号和右括号数量
  • 递归尝试添加左括号或右括号
  • 满足条件时将结果加入列表 
public class Solution
{
    public IList<string> GenerateParenthesis(int n)
    {
        List<string> result = new List<string>();
        BackTrack(result,new StringBuilder(),0,0,n);
        return result;
    }
    private void BackTrack(List<string> result,StringBuilder current,int leftCount,int rightCount,int n)
    {
        //如果当前字符串长度等于2n,说明找到了一个有效组合
        if(current.Length==n*2)   result.Add(current.ToString()),return;
        //如果左括号数量小于n,可以添加左括号
        if(leftCount<n)
        {
            current.Append('(');
            BackTrack(result,current,leftCount+1,rightCount,n);
            current.Length--;//回溯,删除刚才添加的括号

        }
        //如果右括号数量小于左括号数量,可以添加右括号
        if(rightCount<leftCount)
        {
            current.Append(')');
            BackTrack(result,current,leftCount,rightCount+1,n);
            current.Length--;

        }

    }

}

LeetCode 第23题:合并k个升序链表

题目描述

 给你一个链表数组,每个链表都已经按升序排列。请你将所有链表合并到一个升序链表中,返回合并后的链表。

难度:困难

题目链接:23. 合并 K 个升序链表 - 力扣(LeetCode)

示例1:

输入:lists = [[1,4,5],[1,3,4],[2,6]]
输出:[1,1,2,3,4,4,5,6]
解释:链表数组如下:
[
  1->4->5,
  1->3->4,
  2->6
]
合并后:
1->1->2->3->4->4->5->6

示例2:

输入:lists = []
输出:[]

示例3:

输入:lists = [[]]
输出:[]

提示:

  • k==lists.length
  • 0<=k<=10^4
  • 0<=lists[i].length<=500
  • -10^4<=lists[i][j]<=10^4
  • lists[i]按升序排列
  • lists[i].length的总和不超过10^4

解题思路:

方法一:分治合并

将k个链表的合并问题分解为两两合并的子问题

  • 如果链表数组为空,返回null
  • 如果只有一个链表,直接返回
  • 将链表数组分为两半
  • 递归合并左半部分和右半部分
  • 合并得到的两个链表
public class Solution
{
    public ListNode MergeKLists(ListNode[] lists)
    {
        if(lists==null || lists.length==0)  return null;
        return MergeSort(lists,0,lists.length-1);
    }
    private ListNode MergeSort(ListNode[] lists,int left,int right)
    {
        if(left==right) return lists[left];
        if(left>right) return null;
        int mid = left+(right-left)/2;
        ListNode leftList = MergeSort(lists,left,mid);
        ListNode rightList = MergeSort(lists,mid+1,right);
        return MergeTwoLists(leftList,rightList);

    }
    private ListNode MergeTwoLists(ListNode l1,ListNode l2)
    {
        ListNode dummy = new ListNode(0);
        ListNode current = dummy;
        while(l1!=null && l2!=null)
        {
            if(l1.val<=l2.val)  current.next = l1,l1=l1.next;
            else  current.next = l2,l2=l2.next;
            current  = current.next;
        }
        current.next = l1 ?? l2;
        return dummy.next;
    }

}

方法二:优先队列

使用优先队列(最小堆)来维护k个链表的当前最小节点。

  • 创建最小堆,将k个链表的头节点加入堆中
  • 每次从堆中取出最小节点,加入结果链表
  • 如果被取出的节点有后继节点,将后继节点加入堆中
  • 重复2~3步骤直到堆为空。
public class Solution
{
    public ListNode MergeKLists(ListNode[] lists)
    {
        if(lists==null lists.length==0) return null;
        //创建优先队列,按节点值升序排序
        var pq = new PriorityQueue<ListNode,int>();
        //将所有链表的头节点加入队列
        foreach(var list in lists)
            {
                if(list!=null) pq.Enqueue(list,list.val);
            }
        ListNode dummy = new ListNode(0);
        ListNode current =  dummy;
        //不断从队列中取出最小节点
        while(pq.Count>0)
        {
            ListNode node = pq.Dequeue();
            current.next = node;
            current = current.next;
            //如果取出的节点还有后继节点,将后继节点加入队列
            if(node.next!=null)  pq.Enqueue(node.next,node.next.val);

        }
          return dummy.next;
    }


}

LeetCode 第24题:两两交换链表中的节点

题目描述

给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即只能进行节点交换) 。

难度:中等

题目链接:24. 两两交换链表中的节点 - 力扣(LeetCode)

示例1:

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

 示例2:
 

输入:head = []
输出:[]

示例3:

输入:head = [1]
输出:[1]

提示:

  • 链表中节点的数目在范围[0,100]内
  • 0<=Node.val<=100

解题思路:递归法

  • 基线条件:空链表或只有一个节点
  • 对于每两个节点: 
  1. 交换这两个节点
  2. 递归处理后续节点
  • 返回新的头节点
public class Solution
{
    public ListNode SwapPairs(ListNode head)
    {
        //基线条件:空链表或只有一个节点
        if(head==null || head.next==null) return head;
        //获取要交换的两个节点
        ListNode first = head;
        ListNode second = head.next;
        //保存后续节点并递归处理
        ListNode next = second.next;
        second.next = first;
        first.next = SwapPairs(next);
        return second;
    }

}


http://www.kler.cn/a/593219.html

相关文章:

  • Java学习------初识JVM体系结构
  • 【C++】 —— 笔试刷题day_6
  • 如何实现一个DNS
  • Lora 中 怎么 实现 矩阵压缩
  • 天翼云:Apache Doris + Iceberg 超大规模湖仓一体实践
  • 1-1 MATLAB深度极限学习机
  • Mac:JMeter 下载+安装+环境配置(图文详细讲解)
  • C#命令行参数用法
  • Python-docx库详解:轻松实现Word文档自动化生成与图片尺寸控制
  • 组播实验--IGMP、IGMP Snooping 及 PIM-DM 协议
  • 大语言模型(LLM)解析:从 GPT 到 DeepSeek(Transformer 结构、主流 LLM 的对比)
  • 在 STM32 的程序中,HAL_UART_Receive_IT 的调用位置
  • 以太坊节点间通信机制 DEVp2p 协议
  • DevEco Studio的使用
  • Unity 运行报错:InvalidOperationException: Insecure connection not allowed 的原因
  • 让 Google Play 成为助力 PC 游戏增长的最佳平台
  • k8s 配置imagePullSecrets仓库认证
  • 国思RDIF低代码快速开发框架 v6.2版本发布
  • 第14周-Seq2Seq模型-NLP
  • 堆排序的思路与常见的问题