22. 括号生成
题目描述
给出n对括号,请编写一个函数来生成所有的由n对括号组成的合法组合。
例如,给出n=3,解集为:
"((()))", "(()())", "(())()", "()()()", "()(())",
package 牛客网名气面试笔试问题2021;
import org.junit.Test;
import 牛客网练习题.Solution;
import java.util.ArrayList;
import java.util.List;
/**
* @Classname 括号的生成
* @Description TODO
* @Date 2021/2/25 20:54
* @Created by xjl
*/
public class 括号的生成 {
@Test
public void test(){
generateParenthesis(2);
}
public ArrayList<String> generateParenthesis2 (int n) {
ArrayList<String> ans = new ArrayList<String>();
dfs(ans, new StringBuilder(), 0, 0, n);
return ans;
}
public List<String> generateParenthesis(int n) {
List<String> ans = new ArrayList<String>();
dfs(ans, new StringBuilder(), 0, 0, n);
return ans;
}
/**
* @description TODO 使用的是的回溯的思想来构造这样的一个 就是一个二叉树的的剪枝思想
* @param: ans
* @param: cur
* @param: left
* @param: right
* @param: max
* @date: 2021/2/25 21:32
* @return: void
* @author: xjl
*/
public void dfs(List<String> ans, StringBuilder cur, int left, int right, int max) {
//判断是的字符串的长度的以便于终止函数的跳出
if (cur.length() == max * 2) {
//添加到结果集中
ans.add(cur.toString());
return;
}
//左边的小于最大值得时候就加入左括号
if (left < max) {
cur.append('(');
dfs(ans, cur, left + 1, right, max);
//这里使用了回溯的方法 删除最后的一个
cur.deleteCharAt(cur.length() - 1);
}
//当右边的小于左边的时候加入右边括号
if (right < left) {
cur.append(')');
dfs(ans, cur, left, right + 1, max);
cur.deleteCharAt(cur.length() - 1);
}
}
}
25. K 个一组翻转链表
给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
package 牛客网名气面试笔试问题2021;
import java.util.List;
/**
* @Classname 链表k个翻转
* @Description TODO
* @Date 2021/2/25 22:20
* @Created by xjl
*/
public class 链表k个翻转 {
public class ListNode{
int val;
ListNode next;
public ListNode (int val){
this.val=val;
}
}
/**
* @description TODO 将给出的链表中的节点每 k\ k k 个一组翻转,返回翻转后的链表 如果链表中的节点数不是 k\ k k 的倍数,将最后剩下的节点保持原样 你不能更改节点中的值,只能更改节点本身
*
* @param: head
* @param: k
* @date: 2021/2/25 22:24
* @return: 牛客网名气面试笔试问题2021.链表k个翻转.ListNode
* @author: xjl
*/
public ListNode reverseKGroup (ListNode head, int k) {
//边界情况的
if (head==null||head.next==null||k<=1)return head;
//创建新的及诶单
ListNode dumpy=new ListNode(-1);
dumpy.next=head;
//前继节点
ListNode prve=dumpy;
while (prve!=null){
//组内的开始节点和结束节点
ListNode start=prve.next;
ListNode end=prve.next;
//定位本组的结束对的节点
for (int i=0;i<k-1&&end!=null;i++){
end=end.next;
}
//如果是的不足一組
if (end==null){break;}
//缓存本组的后的节点
ListNode follow=end.next;
//切断后面的分组
end.next=null;
prve.next=reverse(start);
//翻转完成
start.next=follow;
prve=start;
}
return dumpy.next;
}
/**
* @description TODO 链表的翻转
* @param: head
* @date: 2021/2/25 22:42
* @return: 牛客网名气面试笔试问题2021.链表k个翻转.ListNode
* @author: xjl
*/
private ListNode reverse(ListNode head) {
ListNode prve=null;
ListNode curr=head;
while (curr!=null){
ListNode furture=curr.next;
curr.next=prve;
prve=curr;
curr=furture;
}
return prve;
}
}