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);
        }
    }
}
相关推荐
徐浪老师1 小时前
深入解析贪心算法及其应用实例
算法·贪心算法
软行1 小时前
LeetCode 单调栈 下一个更大元素 I
c语言·数据结构·算法·leetcode
钰爱&2 小时前
【操作系统】Linux之线程同步二(头歌作业)
linux·运维·算法
拒绝头秃从我做起2 小时前
14.最长公共前缀-力扣(LeetCode)
leetcode
Ws_2 小时前
leetcode LCR 068 搜索插入位置
数据结构·python·算法·leetcode
灼华十一2 小时前
数据结构-布隆过滤器和可逆布隆过滤器
数据结构·算法·golang
代码调试3 小时前
Springboot校园失物招领平台
java·spring boot
adam_life3 小时前
OpenJudge_ 简单英文题_04:0/1 Knapsack
算法·动态规划
camellias_4 小时前
SpringBoot(二十三)SpringBoot集成JWT
java·spring boot·后端
tebukaopu1484 小时前
springboot如何获取控制层get和Post入参
java·spring boot·后端