LeetCode-Java(05)

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

两个方法,方法一是先走一遍链表得出链表长度,再走第二遍,找到倒数第n个数。方法二是双指针,首先快指针就比慢指针多走n步,然后这俩指针同步走,快指针走到头了,慢指针也就指向目标节点了。

方法一:

java 复制代码
class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummy = new ListNode(0, head);
        int length = getLength(head);
        ListNode cur = dummy;
        for (int i = 1; i < length - n + 1; ++i) {
            cur = cur.next;
        }
        cur.next = cur.next.next;
        ListNode ans = dummy.next;
        return ans;
    }

    public int getLength(ListNode head) {
        int length = 0;
        while (head != null) {
            ++length;
            head = head.next;
        }
        return length;
    }
}

方法二:

java 复制代码
class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummy = new ListNode(0, head);
        ListNode first = head;
        ListNode second = dummy;
        for (int i = 0; i < n; ++i) {
            first = first.next;
        }
        while (first != null) {
            first = first.next;
            second = second.next;
        }
        second.next = second.next.next;
        ListNode ans = dummy.next;
        return ans;
    }
}

20. 有效的括号

括号匹配,肯定用栈啊

java 复制代码
class Solution {
public boolean isValid(String s) {
        if(s.isEmpty())
            return true;
        Stack<Character> stack=new Stack<Character>();
        for(char c:s.toCharArray()){
            if(c=='(')
                stack.push(')');
            else if(c=='{')
                stack.push('}');
            else if(c=='[')
                stack.push(']');
            else if(stack.empty()||c!=stack.pop())
                return false;
        }
    return stack.empty();
    }
}

给定的字符串s = "{([])()}"

  • 遇到'{'时,将对应的右括号'}'压入栈中。 栈内变化:}
  • 遇到'('时,将对应的右括号')'压入栈中。 栈内变化:},)
  • 遇到'['时,将对应的右括号']'压入栈中。 栈内变化:},),]
  • 遇到']'时,检查栈顶元素是否为']',如果不是则返回false,否则将栈顶元素弹出。 栈内变化:},)
  • 遇到')'时,检查栈顶元素是否为')',如果不是则返回false,否则将栈顶元素弹出。 栈内变化:}
  • 遇到'('时,将对应的右括号')'压入栈中。 栈内变化:},)
  • 遇到')'时,检查栈顶元素是否为')',如果不是则返回false,否则将栈顶元素弹出。 栈内变化:}
  • 遇到'}'时,检查栈顶元素是否为'}',如果不是则返回false,否则将栈顶元素弹出。 栈内变化:empty
  • 当遍历完所有字符后,如果栈为空,则说明括号是合法的,返回true;否则返回false

21. 合并两个有序链表

递归写法就是比较大小

java 复制代码
class Solution {
    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
        if(list1 == null){
            return list2;
        }
        if(list2 == null){
            return list1;
        }
        if(list1.val <= list2.val){
            list1.next = mergeTwoLists(list1.next, list2);
            return list1;
        }else{

            list2.next = mergeTwoLists(list1, list2.next);
            return list2;
        }     
    }
}

非递归:首先判断特殊情况(为空时),定义一个newhead=初始值最小的那个,然后h1或者h2向后移位,每次比较h1和h2的大小,谁小就连谁。最后当有一个连完了,直接把另一个整个接上就行。

java 复制代码
class Solution {
    public ListNode mergeTwoLists(ListNode pHead1, ListNode pHead2) {
        if (pHead1 == null) return pHead2;
        else if (pHead2 == null) return pHead1;
        else {
            ListNode newhead=new ListNode(-1);
            ListNode p = newhead;
            while (pHead1 != null && pHead2 != null) {
                if (pHead1.val < pHead2.val) {
                    p.next = pHead1;
                    p=p.next;
                    pHead1 = pHead1.next;
                } else {
                    p.next = pHead2;
                    p=p.next;
                    pHead2 = pHead2.next;
                }
            }
            if(pHead1==null) p.next=pHead2;
            else p.next=pHead1;
            return newhead.next;
        }
    }
}

22. 括号生成 ⭐⭐

  • 当前左右括号都有大于 000 个可以使用的时候,才产生分支;
  • 产生左分支的时候,只看当前是否还有左括号可以使用;
  • 产生右分支的时候,还受到左分支的限制,右边剩余可以使用的括号数量一定得在严格大于左边剩余的数量的时候,才可以产生分支;
  • 在左边和右边剩余的括号数都等于 000 的时候结算。
java 复制代码
import java.util.ArrayList;
import java.util.List;

public class Solution {

    // 做加法

    public List<String> generateParenthesis(int n) {
        List<String> res = new ArrayList<>();
        // 特判
        if (n == 0) {
            return res;
        }

        dfs("", 0, 0, n, res);
        return res;
    }

    /**
     * @param curStr 当前递归得到的结果
     * @param left   左括号已经用了几个
     * @param right  右括号已经用了几个
     * @param n      左括号、右括号一共得用几个
     * @param res    结果集
     */
    private void dfs(String curStr, int left, int right, int n, List<String> res) {
        if (left == n && right == n) {
            res.add(curStr);
            return;
        }

        // 剪枝
        if (left < right) {
            return;
        }

        if (left < n) {
            dfs(curStr + "(", left + 1, right, n, res);
        }
        if (right < n) {
            dfs(curStr + ")", left, right + 1, n, res);
        }
    }
}

优化一下

java 复制代码
class Solution {
    public List<String> generateParenthesis(int n) {
        List<String> res = new ArrayList<>();
        backtracking(res, new StringBuilder(), 0, 0, n);
        return res;
    }

    public void backtracking(List<String> res, StringBuilder cur, int open, int close, int max) {
        if (cur.length() == max*2) {
            res.add(cur.toString());
            return;
        }

        if (open < max) {
            cur.append('(');
            backtracking(res, cur, open+1, close, max);
            cur.deleteCharAt(cur.length()-1);
        }

        if (close < open) {
            cur.append(')');
            backtracking(res, cur, open, close+1, max);
            cur.deleteCharAt(cur.length()-1);
        }
    }
}
相关推荐
wuminyu9 小时前
专家视角看Java字节码加载与存储指令机制
java·linux·c语言·jvm·c++
MediaTea10 小时前
AI 术语通俗词典:C4.5 算法
人工智能·算法
Navigator_Z10 小时前
LeetCode //C - 1033. Moving Stones Until Consecutive
c语言·算法·leetcode
WBluuue10 小时前
数据结构与算法:莫队(一):普通莫队与带修莫队
c++·算法
callJJ10 小时前
Spring Data Redis 两种编程模型详解:同步 vs 响应式
java·spring boot·redis·python·spring
风筝在晴天搁浅11 小时前
n个六面的骰子,扔一次之后和为k的概率是多少?
算法
wbs_scy11 小时前
Linux线程同步与互斥(三):线程同步深度解析之POSIX 信号量与环形队列生产者消费者模型,从原理到源码彻底吃透
java·开发语言
MATLAB代码顾问12 小时前
Python实现蜂群算法优化TSP问题
开发语言·python·算法
代码飞天12 小时前
机器学习算法和函数整理——助力快速查阅
人工智能·算法·机器学习
jiushiapwojdap12 小时前
LU分解法求解线性方程组Matlab实现
数据结构·其他·算法·matlab