LeetCodeHot11-15

这篇博客介绍了LeetCode中关于字符串和链表的几道经典算法题,包括电话号码的字母组合、删除链表倒数第N个节点、括号匹配以及合并两个有序链表。通过示例代码详细讲解了解题思路和回溯法的应用,适合提升编程能力和算法理解。
摘要由CSDN通过智能技术生成

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);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值