17- 电话号码的字母组合
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
示例
1:
输入:digits = “23” 输出:[“ad”,“ae”,“af”,“bd”,“be”,“bf”,“cd”,“ce”,“cf”] 示例
2:
输入:digits = “” 输出:[] 示例
3:
输入:digits = “2” 输出:[“a”,“b”,“c”]
class Solution {
public List<String> letterCombinations(String digits) {
List<String> combinations = new ArrayList<>();
if(digits.length()==0) return combinations;
Map<Character, String> phoneMap = new HashMap<>() {{
put('2', "abc");
put('3', "def");
put('4', "ghi");
put('5', "jkl");
put('6', "mno");
put('7', "pqrs");
put('8', "tuv");
put('9', "wxyz");
}};
//这里index是指的第i个数字
backTrack(combinations,phoneMap,digits,0,new StringBuffer());
return combinations;
}
//回溯函数
public void backTrack(List<String> combinations, Map<Character, String> phoneMap, String digits, int index, StringBuffer combination) {
//结束回调条件
if(index == digits.length()){
//索引位置等于数字长度后,字母选择完毕,加入list
combinations.add(combination.toString());
}else{
//根据索引位置取出数字对应字母
char digit = digits.charAt(index);
String letters = phoneMap.get(digit);
int lettersCount = letters.length();
//选取单个字符对应的不同的子母
for (int i = 0; i < lettersCount; i++) {
combination.append(letters.charAt(i));
backTrack(combinations, phoneMap, digits, index + 1, combination);
combination.deleteCharAt(index);
}
}
}
}
19. 删除链表的倒数第 N 个结点
给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode pre = new ListNode(0);
if(head==null) return head;
//标记头节点,防止头节点删除
pre.next = head;
//设置前后快慢指针
ListNode start = pre,end = pre;
//让快指针先走n步
while(n > 0) {
start = start.next;
n--;
}
//t快慢指针同时走,当start的下一个节点是空时候,end到倒数第n个节点的前一个节点
while(start.next != null) {
start = start.next;
end = end.next;
}
//删除
end.next = end.next.next;
return pre.next;
}
}
20-括号匹配
class Solution {
public boolean isValid(String s) {
if(s.length()==0) return true;
Deque<Character> stack = new LinkedList<>();
char[] c = s.toCharArray();
for(int i=0;i<c.length;i++){
//比较当前字符和栈顶字符是否匹配
if(!stack.isEmpty()){
char t = stack.peek();
if(t=='('&&c[i]==')'
|| t=='[' && c[i]==']'
|| t=='{' && c[i]=='}'){
stack.pop();
continue;
}
}
//把每一个字符入栈
stack.push(c[i]);
}
return stack.isEmpty();
}
}
21-合并两个有序链表
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
//设置两个指针,一个工作指针,一个标记头节点
ListNode pre = new ListNode(0);
ListNode cur = pre;
while(l1!=null&&l2!=null){
if(l1.val>l2.val){
cur.next = l2;
l2=l2.next;
}else{
cur.next = l1;
l1=l1.next;
}
cur = cur.next;
}
//把不为空的链表链接到cur
cur.next = l1 == null ? l2 : l1;
return pre.next;
}
}
22-括号生成
数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
示例 1:
输入:n = 3 输出:["((()))","(()())","(())()","()(())","()()()"]
示例 2:输入:n = 1 输出:["()"]
class Solution {
/**
*回溯模板:
* def function(路径,选择列表):
* if 结束条件
* list.add(路径)
* return
* for 选择 in 选择列表:
* 做选择
* function(路径,选择列表)
* 撤销选择
*
*
*/
public List<String> generateParenthesis(int n) {
List<String> ans = new ArrayList<>();
backTrack(ans,new StringBuilder(),0,0,n);
return ans;
}
//回溯函数
//open‘(’括号的个数。close‘)’括号的个数
public void backTrack(List<String> ans,StringBuilder cur,int open,int close,int max){
//结束条件:长度等于n的两倍时
if(cur.length()==max*2){
ans.add(cur.toString());
return;
}
//两个括号的数量应该是相等的,如果'('数量小于max时,可以添加'(',直到有max个'('
if(open<max){
cur.append('(');
backTrack(ans,cur,open+1,close,max);
//撤销添加
cur.deleteCharAt(cur.length()-1);
}
//close < open,添加')'括号
if(close < open){
cur.append(')');
backTrack(ans,cur,open,close+1,max);
cur.deleteCharAt(cur.length()-1);
}
}
}