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

目录

17.电话号码的组合

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

解法一:栈

解法二:list存储结点


17.电话号码的组合

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

思路:

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

代码:

    public static List letterCombinations(String digits) {
        //存储最终的结果
        List combinations = new ArrayList();
        //如果输入的为空
        if (digits.length() == 0) {
            return combinations;
        }
        //用HashMap存储数字以及对应的字母
        Map 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");
        }};
        backtrack(combinations, phoneMap, digits, 0, new StringBuffer());
        return combinations;
    }

    //回溯函数
    public static void backtrack(List combinations, Map 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个节点

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

解法一:栈

 思路:

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

代码:

public ListNode removeNthFromEnd(ListNode head, int n) {

        //具有虚拟头结点的链表dummy,防止出现删除第一个结点要分别讨论的情况
        ListNode dummy = new ListNode(-1, head);
        //栈
        Stack 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 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;

    }

你可能感兴趣的:(力扣HOOT100,java,开发语言,算法,leetcode)