leetcode HOT100 17.电话号码的组合 19.删除链表倒数第n个节点

目录

17.电话号码的组合

19.删除链表的倒数第N个节点

解法一:栈

解法二:list存储结点


17.电话号码的组合

思路:

首先使用哈希表存储每个数字对应的所有可能的字母,然后进行回溯操作。每次取电话号码的一位数字,从哈希表中获得该数字对应的所有可能的字母,并将其中的一个字母插入到已有的字母排列后面,然后继续处理电话号码的后一位数字,直到到达最后一个数字,即得到一个完整的字母排列。然后进行回退操作,遍历其余的字母排列。

代码:

    public static List<String> letterCombinations(String digits) {
        //存储最终的结果
        List<String> combinations = new ArrayList<String>();
        //如果输入的为空
        if (digits.length() == 0) {
            return combinations;
        }
        //用HashMap存储数字以及对应的字母
        Map<Character, String> phoneMap = new HashMap<Character, String>() {{
            put('2', "abc");
            put('3', "def");
            put('4', "ghi");
            put('5', "jkl");
            put('6', "mno");
            put('7', "pqrs");
            put('8', "tuv");
            put('9', "wxyz");
        }};
        backtrack(combinations, phoneMap, digits, 0, new StringBuffer());
        return combinations;
    }

    //回溯函数
    public static void backtrack(List<String> combinations, Map<Character, String> phoneMap, String digits, int index, StringBuffer combination) {

        //如果到达末尾,则将这个字符串添加到最终结果中,并回溯
        if (index == digits.length()) {
            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临时存储,当递归进入到最后一个数字时,就会将字符串添加到combinations中,因此,下次
                //再使用时,要将combination中存储的内容删除
                combination.deleteCharAt(index);
            }
        }
    }

19.删除链表的倒数第N个节点

解法一:栈

 思路:

节点依次入栈。根据栈「先进后出」的原则,我们弹出栈的第n 个节点就是需要删除的节点,并且目前栈顶的节点就是待删除节点的前驱节点。只需要前驱节点指向它下一个的下一个结点即可。

代码:

public ListNode removeNthFromEnd(ListNode head, int n) {

        //具有虚拟头结点的链表dummy,防止出现删除第一个结点要分别讨论的情况
        ListNode dummy = new ListNode(-1, head);
        //栈
        Stack<ListNode> stack = new Stack<>();
        //当前指针
        ListNode cur = dummy;
        //结点依次入栈
        while (cur != null) {
            stack.push(cur);
            cur = cur.next;
        }
        //依次弹栈
        for (int i = 0; i < n; ++i) {
            stack.pop();
        }
        //指向顶峰的结点
        ListNode prev = stack.peek();
        //跳过要删除的那个结点
        prev.next = prev.next.next;
        //跳过虚拟头结点
        ListNode ans = dummy.next;
        
        return ans;
    }

解法二:list存储结点

思路:

用list依次存储结点,然后删除倒数第n个元素,将剩余的元素用头插法重新建立链表。

代码:

public ListNode removeNthFromEnd (ListNode head, int n) {
        

        ArrayList<Integer> list = new ArrayList<>();
        if (head == null) {
            return null;
        }

        //结点依次存入list
        while (head != null) {
            list.add(head.val);
            head = head.next;
        }
        //删除倒数第n个结点
        list.remove(list.size() - n);
        //如果恰好有一个,并且已经删除,返回null
        if (list.isEmpty()) {
            return null;
        }
        //尾插法建立链表
        ListNode newHead = new ListNode(list.get(0));
        ListNode cur = newHead;
        for (int i = 1; i < list.size(); i++) {
            cur.next = new ListNode(list.get(i));
            cur = cur.next;
        }

        return newHead;

    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值