力扣(顺序-中等题-题解数量从高到低)


1019. 链表中的下一个更大节点

/**
 * 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 int[] nextLargerNodes(ListNode head) {

        // 将链表转换为数组, 然后采用单调栈实现
        // 如果后面的数比前面的数大,那么将前面保存的数弹出栈,然后修改结果数组.
        List<Integer> cur = new ArrayList<>();

        while(head!=null){
            cur.add(head.val);
            head = head.next;
        }
        int n = cur.size();
        int[] ans = new int[n];
        for(int i = 0;i<n;i++)
            ans[i] = cur.get(i);
        

        int[] res = new int[n];

        Stack<Integer> s = new Stack();

        for(int i = 0;i<n;i++){
            while(s.size()>0&&ans[s.peek()]<ans[i])
                res[s.pop()] = ans[i];
            s.push(i);
        }
        return res;


    }
}

3. 无重复字符的最长子串

class Solution {
    public int lengthOfLongestSubstring(String s) {
        // 双指针,采用hashmap存储重复的值,存储中间最大值。
        HashMap<Character, Integer> m = new HashMap<>();

        char[] ss = s.toCharArray();
        int n = ss.length;
        int max = 0;
        for(int i = 0, j = 0;i<n&&j<n;){
            if(m.getOrDefault(ss[j], 0)==0){
                m.put(ss[j], 1);
                j++;
            }
            else{
                m.put(ss[i], m.get(ss[i])-1);
                i++;
            }
            max = Math.max(max, j-i);
        }
        return max;


    }
}

2. 两数相加

/**
 * 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 addTwoNumbers(ListNode l1, ListNode l2) {
        // 标志位,新建链表节点。
        ListNode head = new ListNode(0);
        ListNode cur = head;
        int tag = 0;

        while(l1!=null&&l2!=null){
            ListNode tmp = new ListNode((l1.val+l2.val+tag)%10);
            cur.next = tmp;
            cur = cur.next;
            tag = l1.val+l2.val+tag >=10 ? 1 : 0;
            l1 = l1.next;
            l2 = l2.next;
        }
        if(l1!=null||l2!=null){
            if(l1==null)
                l1=l2;

            if(tag==0){
                cur.next = l1;
            }
            else{
                while(l1!=null){
                    int cur_head_val = l1.val;
                    l1.val = (tag + l1.val)%10;
                    tag = tag + cur_head_val >=10 ? 1 : 0;
                    cur.next = l1;
                    cur = cur.next;
                    l1 = l1.next;
                }
            }
        }
        if(tag==1){
            ListNode tmp = new ListNode(tag);
            cur.next = tmp;
        }
        return head.next;
    }
}

19. 删除链表的倒数第 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 initial = new ListNode();
        initial.next = head;

        ListNode cur = initial;

        int count = 0;
        while(head != null){
            if(count<n)
                count++;
            else
                cur = cur.next;
            head = head.next;
        }
        
        cur.next = cur.next.next;
        return initial.next;

    }
}

5. 最长回文子串

class Solution {
    public String longestPalindrome(String s) {
        // 二维数组,动态规划

        char[] ss = s.toCharArray();

        int n = ss.length;
        int[][] dp = new int[n][n];
        String res  = "";
        int max = 0;

        for(int i = 0;i<n;i++){
            for(int j = 0;j<=i;j++){
                if((i==j||i-j<=2)&&ss[i]==ss[j])
                    dp[i][j] = 1;
                else if(ss[i]==ss[j]&&dp[i-1][j+1]==1)
                    dp[i][j] = 1;
                
                if(dp[i][j]==1&&i-j+1>max){
                    max = i-j+1;
                    res = s.substring(j,i+1);
                }
            }
        }
        return res;

    }
}

7. 整数反转

class Solution {
    public int reverse(int x) {
        // 注意越界情况

        int res = 0;
        int pre = 0;
        while(x!=0){
            pre = res;
            int tmp = x%10;
            x  =x/10;
            res = res*10 + tmp;
            if((int)res/10!=(int)pre)
                return 0;
        }
        return res;
    }
}

53. 最大子数组和

class Solution {
    public int maxSubArray(int[] nums) {
        // 动态规划,dp数组保存当前最长的

        int n = nums.length;
        int max = Integer.MIN_VALUE;
        int[] dp = new int[n];

        for(int i = 0;i<n;i++){
            if(i==0)
                dp[i] = nums[i];
            else{
                if(dp[i-1]>0)
                    dp[i] = dp[i-1] + nums[i];
                else
                    dp[i] = nums[i];
            }
            max = Math.max(max, dp[i]);
        }
        return max;
    }    
}

15. 三数之和

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        // 左右指针,固定一个指针
      	// 注意去重

        int n = nums.length;
        Arrays.sort(nums);

        List<List<Integer>> res = new ArrayList<>();

        HashSet<Integer> s = new HashSet<>();
        for(int i = 0; i<n;i++){
            if(s.contains(nums[i]))
                continue;
            s.add(nums[i]);
            HashSet<Integer> ss = new HashSet<>();

            for(int left = i+1, right = n-1;left<right;){
                int a = nums[i];
                int b = nums[left];
                int c = nums[right];
                if(a + b + c==0&&!ss.contains(b)){
                    List<Integer> tmp = new ArrayList<>();
                    tmp.add(a);
                    tmp.add(b);
                    tmp.add(c);
                    res.add(tmp);

                    ss.add(b);
                    left++;
                }
                else if(a + b + c > 0)
                    right--;
                else
                    left++;
            }
        }
        return res;


    }
}

46. 全排列

class Solution {
    public List<List<Integer>> permute(int[] nums) {
        // 回溯
        // 注意,在递归函数中,重新构建数组并传入
        List<List<Integer>> res = new ArrayList<>();
        List<Integer> tmp = new ArrayList<>();
        dfs(nums, nums.length, res, tmp);
        return res;
    }

    void dfs(int[] nums, int length, List<List<Integer>> res, List<Integer> tmp){
        if(tmp.size() == length){
            res.add(new ArrayList<>(tmp));
            return;
        }

        for(int i = 0; i<nums.length;i++){   
            tmp.add(nums[i]);
            int[] cur = new int[nums.length-1];
            for(int j = 0;j<i;j++)
                cur[j] = nums[j];
            
            for(int j = i+1;j<nums.length;j++)
                cur[j-1] = nums[j];

            dfs(cur, length, res, tmp);
            tmp.remove(tmp.size()-1);
        }
    }
}

28. 找出字符串中第一个匹配项的下标

class Solution {
    public int strStr(String haystack, String needle) {
        int n = haystack.length();
        int m = needle.length();

        for(int i = 0;i<=n-m;i++)
            if(haystack.substring(i,i+m).equals(needle))
                return i;
        return -1;
    }
}

17. 电话号码的字母组合

class Solution {

    public List<String> letterCombinations(String digits) {
        // 可以用回溯进行排列
        
        
        HashMap<Character, String> m = new HashMap<>();
        m.put('2', "abc");
        m.put('3', "def");
        m.put('4', "ghi");
        m.put('5', "jkl");
        m.put('6', "mno");
        m.put('7', "pqrs");
        m.put('8', "tuv");
        m.put('9', "wxyz");
        char[] s = digits.toCharArray();

        List<String> res = new ArrayList<>();
        if(digits.equals(""))
            return res;       
        StringBuilder tmp = new StringBuilder();
        dfs(s, 0, s.length, m, res, tmp);
        return res;
    }
    void dfs(char[] s, int index, int len, HashMap m, List<String> res, StringBuilder tmp){
        if(tmp.length()==len){
            res.add(new String(tmp.toString()));
            return;
        }
        for(int i = index; i<len; i++){
            String ss = (String) m.get(s[i]);
            char[] str = ss.toCharArray();
            for(int j = 0;j<str.length;j++){
                tmp.append(str[j]);
                dfs(s, i+1, len, m, res, tmp);
                tmp.delete(tmp.length()-1, tmp.length());
            }
        }
    }
}

11. 盛最多水的容器

class Solution {
    public int maxArea(int[] height) {
        // 左右指针, 需要注意的是:当前面积, 
        // 如果移动的指针的高度小于当前高度,那么面积一定比当前小
        int max = 0;
        for(int left = 0, right = height.length-1;left<right;){
            max = Math.max(Math.min(height[left], height[right])*(right-left), max);
            if(height[left]<=height[right])
                left++;
            else
                right--;
        }
        return max;
    }
}

55. 跳跃游戏

class Solution {
    public boolean canJump(int[] nums) {
        // 设置跳到最远的右指针,每次更新
        int right = 0;
        for(int i = 0;i<nums.length&&i<=right;i++)
            right = Math.max(right, i + nums[i]);
      
        return right >= nums.length-1 ? true : false;
    }
}

22. 括号生成

class Solution {
    public List<String> generateParenthesis(int n) {
        // 思路:"(" + 遍历左侧 + ")" + 遍历右侧

        List<List<String>> res =new ArrayList<>();
        List<String> a = new ArrayList<>();
        a.add("");
        res.add(a);
        List<String> b = new ArrayList<>();
        b.add("()");
        res.add(b);

        for(int i = 2;i<=n;i++){
            List<String> tmp = new ArrayList<>();
            for(int j = 0;j<i;j++){
                List<String> p = res.get(j);
                List<String> q = res.get(i-j-1);
                for(int k = 0;k<p.size();k++){
                    for(int l = 0;l<q.size();l++){
                        tmp.add(new String("(" + p.get(k) + ")" + q.get(l)));
                    }
                }
            }
            res.add(tmp);
        }
        return res.get(res.size()-1);
    }
}

198. 打家劫舍

class Solution {
    public int rob(int[] nums) {
        // 简单的动态规划
        int n = nums.length;
        int[] dp = new int[n];

        if(n<=2)
            return n==1? nums[0] : Math.max(nums[0], nums[1]);
        
        dp[0] = nums[0];
        dp[1] = Math.max(nums[0], nums[1]);
        for(int i = 2; i<n; i++)
            dp[i] = Math.max(dp[i-1], dp[i-2] + nums[i]);

        return dp[n-1];
    }
}

6. N 字形变换

class Solution {
    public String convert(String s, int numRows) {
        if(numRows==1)
            return s;
        
        List<StringBuilder> res = new ArrayList<>();

        for(int i = 0;i<numRows;i++)
            res.add(new StringBuilder(""));
        int judge = 1;
        char[] ss = s.toCharArray();
        for(int i = 0, count = 0;i<ss.length;i++){
            res.get(count).append(ss[i]);
            if(judge==1)
                count++;
            else
                count--;
            if(count==0)
                judge = 1;
            else if(count==numRows-1)
                judge = 0;
        }
        String result = "";
        for(int i = 0;i<numRows;i++)
            result += res.get(i).toString();
        return result;
    }
}

122. 买卖股票的最佳时机 II

class Solution {
    public int maxProfit(int[] prices) {
        if(prices.length==1)
            return 0;
        
        int sum = 0;
        for(int i = 1;i<prices.length;i++)
            if(prices[i]>prices[i-1])
                sum += prices[i]-prices[i-1];
        
        return sum;

    }
}

102. 二叉树的层序遍历

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        // 层序遍历
        List<List<Integer>> res = new ArrayList<>();

        Queue<TreeNode> cur = new LinkedList();
        if(root!=null)
            cur.add(root);

        while(cur.size()!=0){
            Queue<TreeNode> tmp = new LinkedList();
            List<Integer> a = new ArrayList<>();
            while(cur.size()!=0){
                TreeNode node = cur.poll();
                if(node.left!=null)
                    tmp.add(node.left);
                if(node.right!=null)
                    tmp.add(node.right);
                a.add(node.val);
            }
            cur = tmp;
            res.add(a);
        }
        return res;
    }
}

63. 不同路径 II

class Solution {
    public int uniquePathsWithObstacles(int[][] obstacleGrid) {
        // dp
        int n = obstacleGrid.length;
        int m = obstacleGrid[0].length;
        int[][] dp = new int[n][m];

        for(int i = 0; i < n; i++){
            for(int j = 0; j < m; j++){
                if(obstacleGrid[i][j] == 1)
                    dp[i][j] = 0;
                else if(i==0&&j==0)
                    dp[i][j] = 1;
                else if(i==0)
                    dp[i][j] = dp[i][j-1];
                else if(j==0)
                    dp[i][j] = dp[i-1][j];
                else
                    dp[i][j] = dp[i-1][j] + dp[i][j-1];
            }
        }
        return dp[n-1][m-1];

    }
}

142. 环形链表 II

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode detectCycle(ListNode head) {
        // 快慢指针
        ListNode pre = head;
        ListNode last = head;

        while(pre!=null&&pre.next!=null){
            pre = pre.next.next;
            last = last.next;
            if(pre==last){
                ListNode cur = head;
                while(cur!=last){
                    cur = cur.next;
                    last = last.next;
                }
                return cur;
            }
        }
        return null;
    }   
}

209. 长度最小的子数组

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        // 快慢指针

        int left = 0;
        int right = 0;
        int len = Integer.MAX_VALUE;
        for(int i = 0, sum = 0; right <= nums.length;){
            if(sum < target){
                if(right==nums.length)
                    break;
                sum += nums[right];
                right++;
            }
            else{
                len = Math.min(right-left, len);
                sum -= nums[left];
                left++;
            }
        }
        return len == Integer.MAX_VALUE ? 0 : len;
    }
}
posted @ 2023-04-11 11:11  maxzhangxiaotao  阅读(27)  评论(0编辑  收藏  举报