[Leedcode][JAVA][第22题括号生成][DFS][BFS][动态规划]

【问题描述】22. 括号生成

数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
示例:输入:n = 3
输出:["((()))","(()())","(())()","()(())","()()()"]

【解答思路】

image.png

  • 左括号数量需要一直大于等于右数量
  • 左括号数量和右括号数量小于等于总数n
  • 左括号数量和右括号数均等于总数n 得出结果
1.深度遍历 DFS (回溯算法)

时间复杂度:O(N^2) 空间复杂度:O(N)
减法

import java.util.ArrayList;
import java.util.List;public class Solution {// 做减法public List<String> generateParenthesis(int n) {List<String> res = new ArrayList<>();// 特判if (n == 0) {return res;}// 执行深度优先遍历,搜索可能的结果dfs("", n, n, res);return res;}/*** @param curStr 当前递归得到的结果* @param left   左括号还有几个可以使用* @param right  右括号还有几个可以使用* @param res    结果集*/private void dfs(String curStr, int left, int right, List<String> res) {// 因为每一次尝试,都使用新的字符串变量,所以无需回溯// 在递归终止的时候,直接把它添加到结果集即可,注意与「力扣」第 46 题、第 39 题区分if (left == 0 && right == 0) {res.add(curStr);return;}// 剪枝(如图,左括号可以使用的个数严格大于右括号可以使用的个数,才剪枝,注意这个细节)if (left > right) {return;}if (left > 0) {dfs(curStr + "(", left - 1, right, res);}if (right > 0) {dfs(curStr + ")", left, right - 1, res);}}
}作者:liweiwei1419
链接:https://leetcode-cn.com/problems/generate-parentheses/solution/hui-su-suan-fa-by-liweiwei1419/

加法

import java.util.ArrayList;
import java.util.List;public class Solution {// 做加法public List<String> generateParenthesis(int n) {List<String> res = new ArrayList<>();// 特判if (n == 0) {return res;}dfs("", 0, 0, n, res);return res;}/*** @param curStr 当前递归得到的结果* @param left   左括号已经用了几个* @param right  右括号已经用了几个* @param n      左括号、右括号一共得用几个* @param res    结果集*/private void dfs(String curStr, int left, int right, int n, List<String> res) {if (left == n && right == n) {res.add(curStr);return;}// 剪枝if (left < right) {return;}if (left < n) {dfs(curStr + "(", left + 1, right, n, res);}if (right < n) {dfs(curStr + ")", left, right + 1, n, res);}}
}

** 栈实现**

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Stack;public class Solution {class Node {/*** 当前得到的字符串*/private String res;/*** 剩余左括号数量*/private int left;/*** 剩余右括号数量*/private int right;public Node(String str, int left, int right) {this.res = str;this.left = left;this.right = right;}}// 注意:这是深度优先遍历public List<String> generateParenthesis(int n) {List<String> res = new ArrayList<>();if (n == 0) {return res;}// 查看了 Stack 源码,官方推荐使用 Deque 对象,// 注意:只使用栈相关的接口,即只使用 `addLast()` 和 `removeLast()`Deque<Node> stack = new ArrayDeque<>();stack.addLast(new Node("", n, n));while (!stack.isEmpty()) {Node curNode = stack.removeLast();if (curNode.left == 0 && curNode.right == 0) {res.add(curNode.res);}if (curNode.left > 0) {stack.addLast(new Node(curNode.res + "(", curNode.left - 1, curNode.right));}if (curNode.right > 0 && curNode.left < curNode.right) {stack.addLast(new Node(curNode.res + ")", curNode.left, curNode.right - 1));}}return res;}
}作者:liweiwei1419
链接:https://leetcode-cn.com/problems/generate-parentheses/solution/hui-su-suan-fa-by-liweiwei1419/
2. 广度遍历 BFS

时间复杂度:O(N^2) 空间复杂度:O(N)

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;public class Solution {class Node {/*** 当前得到的字符串*/private String res;/*** 剩余左括号数量*/private int left;/*** 剩余右括号数量*/private int right;public Node(String str, int left, int right) {this.res = str;this.left = left;this.right = right;}}public List<String> generateParenthesis(int n) {List<String> res = new ArrayList<>();if (n == 0) {return res;}Queue<Node> queue = new LinkedList<>();queue.offer(new Node("", n, n));while (!queue.isEmpty()) {Node curNode = queue.poll();if (curNode.left == 0 && curNode.right == 0) {res.add(curNode.res);}if (curNode.left > 0) {queue.offer(new Node(curNode.res + "(", curNode.left - 1, curNode.right));}if (curNode.right > 0 && curNode.left < curNode.right) {queue.offer(new Node(curNode.res + ")", curNode.left, curNode.right - 1));}}return res;}
}
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;public class Solution {class Node {/*** 当前得到的字符串*/private String res;/*** 剩余左括号数量*/private int left;/*** 剩余右括号数量*/private int right;public Node(String res, int left, int right) {this.res = res;this.left = left;this.right = right;}@Overridepublic String toString() {return "Node{" +"res='" + res + '\'' +", left=" + left +", right=" + right +'}';}}public List<String> generateParenthesis(int n) {List<String> res = new ArrayList<>();if (n == 0) {return res;}Queue<Node> queue = new LinkedList<>();queue.offer(new Node("", n, n));// 总共需要拼凑的字符总数是 2 * nn = 2 * n;while (n > 0) {int size = queue.size();for (int i = 0; i < size; i++) {Node curNode = queue.poll();if (curNode.left > 0) {queue.offer(new Node(curNode.res + "(", curNode.left - 1, curNode.right));}if (curNode.right > 0 && curNode.left < curNode.right) {queue.offer(new Node(curNode.res + ")", curNode.left, curNode.right - 1));}}n--;}// 最后一层就是题目要求的结果集while (!queue.isEmpty()) {res.add(queue.poll().res);}return res;}
} 作者:liweiwei1419
链接:https://leetcode-cn.com/problems/generate-parentheses/solution/hui-su-suan-fa-by-liweiwei1419/
3. 动态规划

image.png

时间复杂度:O(N^2) 空间复杂度:O(N)

import java.util.ArrayList;
import java.util.List;public class Solution {// 把结果集保存在动态规划的数组里public List<String> generateParenthesis(int n) {if (n == 0) {return new ArrayList<>();}// 这里 dp 数组我们把它变成列表的样子,方便调用而已List<List<String>> dp = new ArrayList<>(n);List<String> dp0 = new ArrayList<>();dp0.add("");dp.add(dp0);for (int i = 1; i <= n; i++) {List<String> cur = new ArrayList<>();for (int j = 0; j < i; j++) {List<String> str1 = dp.get(j);List<String> str2 = dp.get(i - 1 - j);for (String s1 : str1) {for (String s2 : str2) {// 枚举右括号的位置cur.add("(" + s1 + ")" + s2);}}}dp.add(cur);}return dp.get(n);}
}作者:liweiwei1419
链接:https://leetcode-cn.com/problems/generate-parentheses/solution/hui-su-suan-fa-by-liweiwei1419/

【总结】

1.搜索使用深度优先遍历 (回溯算法)
  • 广度优先遍历 程序员自己编写节点类 显示使用队列数据结构
  • 深度优先遍历 程序员使用系统栈 递归执行 系统顶栈弹出所需状态信息 无需写结点和显示使用栈
2.动态规划特点

如何设计状态(我是谁)?
状态x从哪里推过来?(我从哪里来?/我要到哪里去?)

动态规划 = 在拓扑序上做递推
自顶向上去递推 自顶向下的递归
1、自底向上:从小规模问题开始,逐渐得到大规模问题的解集;

2、无后效性:后面的结果的得到,不会影响到前面的结果。

3. 思路

DFS => 记忆化搜索 => 动态规划
image.png

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

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

相关文章

java学习(150):文本缓冲流

import javax.imageio.IIOException; import java.io.*; import java.util.Date;//字符输入流 public class FileManagerChar {public static void readCharFile(File file){FileReader fileReadernull;//文本输入流if(file.exists()){try {fileReader new FileReader( file )…

微信小程序初始化 operateWXData:fail invalid scope

初学者开发微信小程序&#xff0c;可以使用云开发来进行微信小程序的开发。 第一次使用开发工具遇到的问题 解决方案&#xff1a;1、找到云开发 2、点击开通&#xff0c;选择合适自己的开发环境&#xff1b; 3、完成后&#xff0c;返回开发工具界面点击项目第一个节点“cloudfu…

matlab win10 gpu加速,win10的Edge浏览器设置GPU硬件加速,大幅度提升浏览器性能

不知道大家对于GPU硬件加速是否有了解&#xff0c;这是现在的浏览器必备的功能&#xff0c;开启后能大幅度提升浏览器的性能&#xff0c;给我们更加顺滑的浏览体验。GPU硬件加速能够利用GPU的图形性能&#xff0c;加速渲染网页中的图像信息。如果我们开启了GPU硬件加速&#xf…

java学习(151):字节输出流

import javax.imageio.IIOException; import java.io.*; import java.util.Date;//字符输入流 public class FileManagerChar {public static void readCharFile(File file){FileReader fileReadernull;//文本输入流if(file.exists()){try {fileReader new FileReader( file )…

[Leedcode][JAVA][第887题][鸡蛋掉落][谷歌面试][动态规划]

【问题描述】 [887. 鸡蛋掉落] 你将获得 K 个鸡蛋&#xff0c;并可以使用一栋从 1 到 N 共有 N 层楼的建筑。每个蛋的功能都是一样的&#xff0c;如果一个蛋碎了&#xff0c;你就不能再把它掉下去。你知道存在楼层 F &#xff0c;满足 0 < F < N 任何从高于 F 的楼层落…

java学习(152):字节缓冲输出流

import javax.imageio.IIOException; import java.io.*; import java.util.Date;//字符输入流 public class FileManagerChar {public static void readCharFile(File file){FileReader fileReadernull;//文本输入流if(file.exists()){try {fileReader new FileReader( file )…

SDUTOJ3469_深度优先搜索练习之神奇的矩环(DFS)

深度优先搜索练习之神奇的矩环 Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Problem Description 小鑫的女朋友被魔王抢走了&#xff01; 魔王留给小鑫一张n*m大的表&#xff0c;上面有各种各样的颜色&#xff0c;用A-Z这26个字母来表示。魔王留给他一个任务…

PHP水果店管理系统,水果店连锁店管理系统实现一体化功能

现在的人们越来越注重养生&#xff0c;特别是饮食养生那么水果就成为了客户的首选之一&#xff0c;随着水果的市场需求越来越大&#xff0c;想开水果店的创业者越来越多&#xff0c;连锁水果店我们看到的店面也越来越多&#xff0c;由于季节或者是时间的问题会很容易导致水果变…

[剑指offer]面试题第[58]题[Leetcode][JAVA][第151题][翻转单词][字符串常用函数总结]

【问题描述】 给定一个字符串&#xff0c;逐个翻转字符串中的每个单词。示例 1&#xff1a; 输入: "the sky is blue" 输出: "blue is sky the"【解答思路】 1. 双指针 倒序遍历字符串确定边界添加单词拼接字符串 返回 时间复杂度&#xff1a;O(N) 空间…

java学习(153):字符输出流

import javax.imageio.IIOException; import java.io.*; import java.util.Date;//字符输入流 public class FileManagerChar {public static void readCharFile(File file){FileReader fileReadernull;//文本输入流if(file.exists()){try {fileReader new FileReader( file )…

java学习(154):文件复制

import javax.imageio.IIOException; import java.io.*; import java.util.Date;//字符输入流 public class FileManagerChar {public static void readCharFile(File file){FileReader fileReadernull;//文本输入流if(file.exists()){try {fileReader new FileReader( file )…

[Leedcode][JAVA][面试题 16.03. 交点]

【问题描述】面试题 16.03. 交点 给定两条线段&#xff08;表示为起点start {X1, Y1}和终点end {X2, Y2}&#xff09;&#xff0c;如果它们有交点&#xff0c;请计算其交点&#xff0c;没有交点则返回空值。要求浮点型误差不超过10^-6。若有多个交点&#xff08;线段重叠&am…

[Leedcode][JAVA][第146题][LRU][哈希表][双向链表]

【问题描述】 LFU 运用你所掌握的数据结构&#xff0c;设计和实现一个 LRU (最近最少使用) 缓存机制。它应该支持以下操作&#xff1a; 获取数据 get 和 写入数据 put 。获取数据 get(key) - 如果密钥 (key) 存在于缓存中&#xff0c;则获取密钥的值&#xff08;总是正数&…

java学习(155):序列化

import javax.imageio.IIOException; import java.io.*; import java.util.Date;//字符输入流 public class FileManagerChar {public static void readCharFile(File file){FileReader fileReadernull;//文本输入流if(file.exists()){try {fileReader new FileReader( file )…

[Leedcode][JAVA][第445题][链表][栈]

【问题描述】445. 两数相加 II 给你两个 非空 链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表。你可以假设除了数字 0 之外&#xff0c;这两个数字都不会以零开头。进阶&#xff1a;如果输入链表不能修改…

java学习(156):反序列化

import javax.imageio.IIOException; import java.io.*; import java.util.Date;//字符输入流 public class FileManagerChar {public static void readCharFile(File file){FileReader fileReadernull;//文本输入流if(file.exists()){try {fileReader new FileReader( file )…

[Leedcode][JAVA][第355题][设计推特][面向对象][哈希表][链表][优先队列]

【问题描述】355 设计推特 设计一个简化版的推特(Twitter)&#xff0c;可以让用户实现发送推文&#xff0c;关注/取消关注其他用户&#xff0c;能够看见关注人&#xff08;包括自己&#xff09;的最近十条推文。你的设计需要支持以下的几个功能&#xff1a;postTweet(userId, …

java学习(157):线程的引入

//线程 public class test102 extends Thread{public void run(){while (true){System.out.println("我是线程1"this.getName());try {Thread.sleep( 1000 );}catch (InterruptedException e){e.printStackTrace();}}} }//线程 public class test103 extends Thread{…

【读书笔记】计算机是怎样跑起来的

2018年底读的&#xff0c;才整理完笔记。说说感想吧&#xff0c;每个章节虽然都是基础的知识&#xff0c;但是每次读起来还是收获颇多&#xff0c;很多自己说不清楚或者不理解的概念&#xff0c;感觉在认识层面有些结成网了。对于每个方面的专业知识&#xff0c;要按需深入学习…

[剑指offer][JAVA]面试题[第23题][合并K个排序链表][分治][优先队列]

【问题描述】23.合并K个排序链表 合并 k 个排序链表&#xff0c;返回合并后的排序链表。请分析和描述算法的复杂度。 示例: 输入: [1->4->5,1->3->4,2->6 ] 输出: 1->1->2->3->4->4->5->6【解答思路】 1. 两两合并 public class Soluti…