字节跳动高频题目(1)

 3,1,42,200,15

121,128,49,25,88

5,146,70,2,4

21,33,55,27,560

11,20,31,53,236

300,26,215,279,438

135,148,9,169,76

22,101,14,54,56

72,206,152,80,39

46,62,104,122,179

3. Longest Substring Without Repeating Characters

Medium

Given a string s, find the length of the longest substring without repeating characters.

Example 1:

Input: s = "abcabcbb"
Output: 3
Explanation: The answer is "abc", with the length of 3.
class Solution {
    public int lengthOfLongestSubstring(String s) {
        Set<Character> set = new HashSet<>();
        char[] ch = s.toCharArray();
        int left = 0;
        int count = 0;
        int ans = 0;
        for(int right = 0; right < ch.length; right++){
            if(!set.contains(ch[right])){
                set.add(ch[right]);
                count = count + 1;
                ans = Math.max(ans, count);
            }else{
                while(set.contains(ch[right])){
                    set.remove(ch[left]);
                    left++;
                    count--;
                }
                set.add(ch[right]);
                count++;
            }
        }
        return ans;
    }
}
class Solution {
    public int lengthOfLongestSubstring(String s) {
        int[] ch = new int[128];
        for(int i=0;i<128;i++){
            ch[i]=-1;
        }
        int ans=0;
        int st=0;
        for(int i=0;i<s.length();i++){
            int c = s.charAt(i);
            if(ch[c]!=-1){
                st=Math.max(st,ch[c]);
            }
            ans=Math.max(ans,i-st+1);
            ch[c]=i+1;
        }
        return ans;
    }
}

1. Two Sum

Easy

Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target.

You may assume that each input would have exactly one solution, and you may not use the same element twice.

You can return the answer in any order.

class Solution {
    public int[] twoSum(int[] nums, int target) {
        Map<Integer, Integer> hashtable = new HashMap<Integer, Integer>();
        for (int i = 0; i < nums.length; ++i) {
            if (hashtable.containsKey(target - nums[i])) {
                return new int[]{hashtable.get(target - nums[i]), i};
            }
            hashtable.put(nums[i], i);
        }
        return new int[0];
    }
}

42. Trapping Rain Water

Hard

Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it can trap after raining.

class Solution {
    public int trap(int[] height) {
        int ans = 0;
        int left = 0, right = height.length - 1;
        int leftMax = 0, rightMax = 0;
        while (left < right) {
            leftMax = Math.max(leftMax, height[left]);
            rightMax = Math.max(rightMax, height[right]);
            if (height[left] < height[right]) {
                ans += leftMax - height[left];
                ++left;
            } else {
                ans += rightMax - height[right];
                --right;
            }
        }
        return ans;
    }
}

200. Number of Islands

Medium

Given an m x n 2D binary grid grid which represents a map of '1's (land) and '0's (water), return the number of islands.

An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.

class Solution {
    void dfs(char[][] grid, int r, int c) {
        int nr = grid.length;
        int nc = grid[0].length;

        if (r < 0 || c < 0 || r >= nr || c >= nc || grid[r][c] == '0') {
            return;
        }

        grid[r][c] = '0';
        dfs(grid, r - 1, c);
        dfs(grid, r + 1, c);
        dfs(grid, r, c - 1);
        dfs(grid, r, c + 1);
    }

    public int numIslands(char[][] grid) {
        if (grid == null || grid.length == 0) {
            return 0;
        }

        int nr = grid.length;
        int nc = grid[0].length;
        int num_islands = 0;
        for (int r = 0; r < nr; ++r) {
            for (int c = 0; c < nc; ++c) {
                if (grid[r][c] == '1') {
                    ++num_islands;
                    dfs(grid, r, c);
                }
            }
        }

        return num_islands;
    }
}

15. 3Sum

Medium

Given an integer array nums, return all the triplets [nums[i], nums[j], nums[k]] such that i != ji != k, and j != k, and nums[i] + nums[j] + nums[k] == 0.

Notice that the solution set must not contain duplicate triplets.

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> ans = new ArrayList<>();
        Arrays.sort(nums);
        for(int i = 0; i < nums.length-2; i++){
            if(nums[i] + nums[i + 1] + nums[i + 2] > 0){
                break;
            }
            if(nums[i] + nums[nums.length - 1] + nums[nums.length -2] < 0){
                continue;
            }
            if(i > 0 && nums[i] == nums[i - 1]){
                continue;
            }
            int j = i + 1;
            int k = nums.length - 1;
            while(j < k){
                if(nums[i] + nums[j] + nums[k] > 0){
                    k--;
                }else if(nums[i] + nums[j] + nums[k] < 0){
                    j++;
                }else{
                    List<Integer> list = new ArrayList<>();
                    list.add(nums[i]);
                    list.add(nums[j]);
                    list.add(nums[k]);
                    ans.add(list);
                    j++;
                    k--;
                    while(j < k && nums[j] == nums[j -1]){
                        j++;
                    }
                    while(j < k && nums[k] == nums[k + 1]){
                        k--;
                    }
                }
            }
        }
        return ans;
    }
}

121. Best Time to Buy and Sell Stock

Easy

You are given an array prices where prices[i] is the price of a given stock on the ith day.

You want to maximize your profit by choosing a single day to buy one stock and choosing a different day in the future to sell that stock.

Return the maximum profit you can achieve from this transaction. If you cannot achieve any profit, return 0.

Example 1:

Input: prices = [7,1,5,3,6,4]
Output: 5
Explanation: Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 6-1 = 5.
Note that buying on day 2 and selling on day 1 is not allowed because you must buy before you sell.
class Solution {
    public int maxProfit(int[] prices) {
        if (prices.length == 1) {
            return 0;
        }
        int[][] dp = new int[prices.length][2];//dp[i][0]表示第i天持有股票的最大收益,dp[i][1]表示第i天不持有股票的最大收益
        dp[0][0] = -prices[0];
        dp[0][1] = 0;
        for (int i = 1; i < prices.length; i++) {
            dp[i][0] = Math.max(dp[i - 1][0],  -prices[i]);//分为是不是今天买入
            dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] + prices[i]);//分为是不是今天买
        }
        return dp[prices.length - 1][1];
    }
}
class Solution {
    public int maxProfit(int[] prices) {
        int cost = Integer.MAX_VALUE, profit = 0;
        for (int price : prices) {
            cost = Math.min(cost, price);
            profit = Math.max(profit, price - cost);
        }
        return profit;
    }
}

128. Longest Consecutive Sequence

Medium

Given an unsorted array of integers nums, return the length of the longest consecutive elements sequence.

You must write an algorithm that runs in O(n) time.

Example 1:

Input: nums = [100,4,200,1,3,2]
Output: 4
Explanation: The longest consecutive elements sequence is [1, 2, 3, 4]. Therefore its length is 4.

class Solution {
    public int longestConsecutive(int[] nums) {
        Set<Integer> numSet = new HashSet<Integer>();
        for (int num : nums) {
            numSet.add(num);
        }

        int longestLength = 0;

        for (int num : numSet) {
            if (!numSet.contains(num - 1)) {
                int currentNum = num;
                int currentLength = 1;

                while (numSet.contains(currentNum + 1)) {
                    currentNum += 1;
                    currentLength += 1;
                }
                longestLength = Math.max(longestLength, currentLength);
            }
        }

        return longestLength;
    }
}

49. Group Anagrams

Solved

Medium

Topics

Companies

Given an array of strings strs, group the anagrams together. You can return the answer in any order.

An Anagram is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        Map<String, List<String>> map = new HashMap<String, List<String>>();
        for (String str : strs) {
            char[] array = str.toCharArray();
            Arrays.sort(array);
            String key = new String(array);
            List<String> list = map.getOrDefault(key, new ArrayList<String>());
            list.add(str);
            map.put(key, list);
        }
        return new ArrayList<List<String>>(map.values());
    }
}
class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        Map<String, List<String>> map = new HashMap<String, List<String>>();
        for (String str : strs) {
            int[] counts = new int[26];
            int length = str.length();
            for (int i = 0; i < length; i++) {
                counts[str.charAt(i) - 'a']++;
            }
            // 将每个出现次数大于 0 的字母和出现次数按顺序拼接成字符串,作为哈希表的键
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < 26; i++) {
                if (counts[i] != 0) {
                    sb.append((char) ('a' + i));
                    sb.append(counts[i]);
                }
            }
            String key = sb.toString();
            List<String> list = map.getOrDefault(key, new ArrayList<String>());
            list.add(str);
            map.put(key, list);
        }
        return new ArrayList<List<String>>(map.values());
    }
}

25. Reverse Nodes in k-Group

Hard

Topics

Companies

Given the head of a linked list, reverse the nodes of the list k at a time, and return the modified list.

k is a positive integer and is less than or equal to the length of the linked list. If the number of nodes is not a multiple of k then left-out nodes, in the end, should remain as it is.

You may not alter the values in the list's nodes, only nodes themselves may be changed.

class Solution {
    public ListNode reverseKGroup(ListNode head, int k) {
        ListNode hair = new ListNode(0);
        hair.next = head;
        ListNode pre = hair;

        while (head != null) {
            ListNode tail = pre;
            // 查看剩余部分长度是否大于等于 k
            for (int i = 0; i < k; ++i) {
                tail = tail.next;
                if (tail == null) {
                    return hair.next;
                }
            }
            ListNode nex = tail.next;
            ListNode[] reverse = myReverse(head, tail);
            head = reverse[0];
            tail = reverse[1];
            // 把子链表重新接回原链表
            pre.next = head;
            tail.next = nex;
            pre = tail;
            head = tail.next;
        }

        return hair.next;
    }

    public ListNode[] myReverse(ListNode head, ListNode tail) {
        ListNode prev = tail.next;
        ListNode p = head;
        while (prev != tail) {
            ListNode nex = p.next;
            p.next = prev;
            prev = p;
            p = nex;
        }
        return new ListNode[]{tail, head};
    }
}

88. Merge Sorted Array

Easy

You are given two integer arrays nums1 and nums2, sorted in non-decreasing order, and two integers m and n, representing the number of elements in nums1 and nums2 respectively.

Merge nums1 and nums2 into a single array sorted in non-decreasing order.

The final sorted array should not be returned by the function, but instead be stored inside the array nums1. To accommodate this, nums1 has a length of m + n, where the first m elements denote the elements that should be merged, and the last n elements are set to 0 and should be ignored. nums2 has a length of n.

Example 1:

Input: nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
Output: [1,2,2,3,5,6]
Explanation: The arrays we are merging are [1,2,3] and [2,5,6].
The result of the merge is [1,2,2,3,5,6] with the underlined elements coming from nums1.
class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        int p1 = 0, p2 = 0;
        int[] sorted = new int[m + n];
        int cur;
        while (p1 < m || p2 < n) {
            if (p1 == m) {
                cur = nums2[p2++];
            } else if (p2 == n) {
                cur = nums1[p1++];
            } else if (nums1[p1] < nums2[p2]) {
                cur = nums1[p1++];
            } else {
                cur = nums2[p2++];
            }
            sorted[p1 + p2 - 1] = cur;
        }
        for (int i = 0; i != m + n; ++i) {
            nums1[i] = sorted[i];
        }
    }
}

5. Longest Palindromic Substring

Medium

Given a string s, return the longest 

palindromic substring in s.

class Solution {
    public String longestPalindrome(String s) {
        if (s == null || s.length() < 1) {
            return "";
        }
        int start = 0, end = 0;
        for (int i = 0; i < s.length(); i++) {
            int len1 = expandAroundCenter(s, i, i);
            int len2 = expandAroundCenter(s, i, i + 1);
            int len = Math.max(len1, len2);
            if (len > end - start) {
                start = i - (len - 1) / 2;
                end = i + len / 2;
            }
        }
        return s.substring(start, end + 1);
    }

    public int expandAroundCenter(String s, int left, int right) {
        while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) {
            --left;
            ++right;
        }
        return right - left - 1;
    }
}

146. LRU Cache ( the second one is better)

Medium

Topics

Companies

Design a data structure that follows the constraints of a Least Recently Used (LRU) cache.

Implement the LRUCache class:

  • LRUCache(int capacity) Initialize the LRU cache with positive size capacity.
  • int get(int key) Return the value of the key if the key exists, otherwise return -1.
  • void put(int key, int value) Update the value of the key if the key exists. Otherwise, add the key-value pair to the cache. If the number of keys exceeds the capacity from this operation, evict the least recently used key.

The functions get and put must each run in O(1) average time complexity.

class LRUCache {

    public LRUCache(int capacity) {
        
    }
    
    public int get(int key) {
        
    }
    
    public void put(int key, int value) {
        
    }
}
class LRUCache {
    // 定义一个内部类 Node,用于双向链表的节点
    class Node {
        int key;
        int value;
        Node prev;
        Node next;

        // 节点构造函数
        Node(int key, int value) {
            this.key = key;
            this.value = value;
        }
    }

    // 用于存储键到节点的映射,简化的哈希表实现
    public Node[] map;
    // 当前缓存中的元素数量
    public int count, capacity;
    // 双向链表的头尾伪节点
    public Node head, tail;
    
    // 构造函数初始化LRUCache
    public LRUCache(int capacity) {
        this.capacity = capacity; // 缓存容量
        count = 0; // 初始元素数量
        map = new Node[10_000 + 1]; // 初始化哈希表
        
        head = new Node(0, 0); // 创建伪头部节点
        tail = new Node(0, 0); // 创建伪尾部节点
        
        // 初始化双向链表
        head.next = tail;
        tail.prev = head;
        
        // 头尾节点的前后指针
        head.prev = null;
        tail.next = null;
    }
    
    // 从双向链表中删除节点
    public void deleteNode(Node node) {
        node.prev.next = node.next;
        node.next.prev = node.prev;
    }
    
    // 将节点添加到双向链表的头部
    public void addToHead(Node node) {
        node.next = head.next;
        node.next.prev = node;
        node.prev = head;
        
        head.next = node;
    }
    
    // 获取节点的值,如果存在则将其移动到链表头部
    public int get(int key) {
        if (map[key] != null) { // 检查键是否存在
            Node node = map[key]; // 获取节点
            int nodeVal = node.value; // 取得节点的值
            
            deleteNode(node); // 从链表中删除节点
            addToHead(node); // 将节点移动到头部
            
            return nodeVal; // 返回节点的值
        } else {
            return -1; // 不存在则返回-1
        }
    }
    
    // 放置或更新节点
    public void put(int key, int value) {
        if (map[key] != null) { // 如果节点已存在
            Node node = map[key]; // 获取节点
            node.value = value; // 更新节点值
            
            deleteNode(node); // 从链表中删除节点
            addToHead(node); // 将节点移动到头部
        } else { // 如果节点不存在
            Node node = new Node(key, value); // 创建新节点
            map[key] = node; // 将节点加入哈希表
            
            if (count < capacity) { // 如果未达到容量限制
                count++; // 增加节点计数
                addToHead(node); // 将节点添加到头部
            } else { // 如果已达到容量限制
                map[tail.prev.key] = null; // 从哈希表中移除尾节点的映射
                deleteNode(tail.prev); // 删除尾节点
                
                addToHead(node); // 将新节点添加到头部
            }
        }
    }
}
public class LRUCache {
    // 双向链表节点定义
    class DLinkedNode {
        int key;
        int value;
        DLinkedNode prev;
        DLinkedNode next;
        public DLinkedNode() {}
        public DLinkedNode(int _key, int _value) { key = _key; value = _value; }
    }

    // 哈希表,用于快速定位节点
    private Map<Integer, DLinkedNode> cache = new HashMap<Integer, DLinkedNode>();
    private int size; // 当前缓存大小
    private int capacity; // 缓存容量
    private DLinkedNode head, tail; // 伪头部和伪尾部节点,便于节点操作

    // 构造函数
    public LRUCache(int capacity) {
        this.size = 0;
        this.capacity = capacity;
        head = new DLinkedNode();
        tail = new DLinkedNode();
        head.next = tail;
        tail.prev = head;
    }

    // 获取节点值的操作
    public int get(int key) {
        DLinkedNode node = cache.get(key);
        if (node == null) {
            return -1; // 未找到返回-1
        }
        // 如果找到,移动该节点到头部
        moveToHead(node);
        return node.value;
    }

    // 添加或修改节点的操作
    public void put(int key, int value) {
        DLinkedNode node = cache.get(key);
        if (node == null) {
            // key不存在,创建新节点
            DLinkedNode newNode = new DLinkedNode(key, value);
            cache.put(key, newNode); // 添加到哈希表
            addToHead(newNode); // 添加到双向链表头部
            ++size;
            if (size > capacity) {
                // 如果超出容量,删除尾部节点
                DLinkedNode tail = removeTail();
                cache.remove(tail.key); // 在哈希表中删除
                --size;
            }
        } else {
            // key存在,更新节点值,并移动到头部
            node.value = value;
            moveToHead(node);
        }
    }

    // 添加节点到头部
    private void addToHead(DLinkedNode node) {
        node.prev = head;
        node.next = head.next;
        head.next.prev = node;
        head.next = node;
    }

    // 从链表中移除节点
    private void removeNode(DLinkedNode node) {
        node.prev.next = node.next;
        node.next.prev = node.prev;
    }

    // 将节点移动到头部
    private void moveToHead(DLinkedNode node) {
        removeNode(node);
        addToHead(node);
    }

    // 移除尾部节点
    private DLinkedNode removeTail() {
        DLinkedNode res = tail.prev;
        removeNode(res);
        return res;
    }
}

70. Climbing Stairs

Easy

You are climbing a staircase. It takes n steps to reach the top.

Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?

class Solution {
    public int climbStairs(int n) {
        int[] dp = new int[n + 1];
        if (n <= 2) {
            return n;
        }
        dp[1] = 1;
        dp[2] = 2;
        //应该这样理解,最后一步要么是两阶要么是一阶,那么如果最后一步迈的是一阶有几种迈法:f(n-1);最后一步迈的是两阶有几种迈法:f(n-2)
        for (int i = 3; i <= n; i++) {
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        return dp[n];
    }
}

2. Add Two Numbers

Medium

You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order, and each of their nodes contains a single digit. Add the two numbers and return the sum as a linked list.

You may assume the two numbers do not contain any leading zero, except the number 0 itself.

class Solution {
    // 定义一个内部类ListNode,通常在题目描述中已给出
    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; }
    }

    // 方法:将两个链表代表的数字相加
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode head = null, tail = null; // 初始化结果链表的头尾节点
        int carry = 0; // 初始化进位变量
        while (l1 != null || l2 != null) { // 遍历两个链表,直到两个链表都遍历完
            int n1 = l1 != null ? l1.val : 0; // 获取当前l1的值,若l1已遍历完,用0代替
            int n2 = l2 != null ? l2.val : 0; // 获取当前l2的值,若l2已遍历完,用0代替
            int sum = n1 + n2 + carry; // 将当前位的两个数字与进位相加

            if (head == null) {
                head = tail = new ListNode(sum % 10); // 如果结果链表为空,初始化头尾节点
            } else {
                tail.next = new ListNode(sum % 10); // 否则,在结果链表尾部添加新节点
                tail = tail.next; // 移动尾节点指针
            }
            carry = sum / 10; // 计算新的进位

            if (l1 != null) {
                l1 = l1.next; // 移动l1指针
            }
            if (l2 != null) {
                l2 = l2.next; // 移动l2指针
            }
        }
        if (carry > 0) {
            tail.next = new ListNode(carry); // 如果最后还有进位,添加到结果链表的尾部
        }
        return head; // 返回结果链表的头节点
    }
}

4. Median of Two Sorted Arrays

Hard

Given two sorted arrays nums1 and nums2 of size m and n respectively, return the median of the two sorted arrays.

The overall run time complexity should be O(log (m+n)).

class Solution {
    // 主方法,用于计算两个排序数组的中位数
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int length1 = nums1.length, length2 = nums2.length;
        int totalLength = length1 + length2;
        // 判断元素总数是奇数还是偶数
        if (totalLength % 2 == 1) {
            int midIndex = totalLength / 2;
            double median = getKthElement(nums1, nums2, midIndex + 1); // 中位数是中间的一个元素
            return median;
        } else {
            int midIndex1 = totalLength / 2 - 1, midIndex2 = totalLength / 2;
            // 中位数是中间两个元素的平均值
            double median = (getKthElement(nums1, nums2, midIndex1 + 1) + getKthElement(nums1, nums2, midIndex2 + 1)) / 2.0;
            return median;
        }
    }

    // 辅助函数,用于找到两个排序数组中的第 k 小的元素
    public int getKthElement(int[] nums1, int[] nums2, int k) {
        int length1 = nums1.length, length2 = nums2.length;
        int index1 = 0, index2 = 0; // 两个数组的起始搜索位置

        while (true) {
            // 边界情况处理
            if (index1 == length1) { // 如果nums1为空,直接返回nums2中的第k小元素
                return nums2[index2 + k - 1];
            }
            if (index2 == length2) { // 如果nums2为空,直接返回nums1中的第k小元素
                return nums1[index1 + k - 1];
            }
            if (k == 1) { // 如果k为1,直接返回两数组当前元素的较小者
                return Math.min(nums1[index1], nums2[index2]);
            }

            // 正常情况下,比较两个数组的第k/2个元素
            int half = k / 2;
            int newIndex1 = Math.min(index1 + half, length1) - 1; // 不越界的情况下取第k/2个元素,否则取最后一个元素
            int newIndex2 = Math.min(index2 + half, length2) - 1;
            int pivot1 = nums1[newIndex1], pivot2 = nums2[newIndex2];
            if (pivot1 <= pivot2) {
                // 如果nums1的中间元素小于等于nums2的,说明nums1的前部分不可能有第k小的元素
                k -= (newIndex1 - index1 + 1); // 减去nums1中排除的元素数量
                index1 = newIndex1 + 1; // 更新nums1的搜索起点
            } else {
                // 同理,排除nums2的前部分
                k -= (newIndex2 - index2 + 1);
                index2 = newIndex2 + 1;
            }
        }
    }
}
class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        // 确保nums1是较短的数组,简化后续的逻辑
        if (nums1.length > nums2.length) {
            return findMedianSortedArrays(nums2, nums1);
        }

        int m = nums1.length;
        int n = nums2.length;
        int left = 0, right = m; // 二分查找的范围
        // median1:前一部分的最大值
        // median2:后一部分的最小值
        int median1 = 0, median2 = 0;

        while (left <= right) {
            // i, j 分别是 nums1 和 nums2 的分割线
            int i = (left + right) / 2;
            int j = (m + n + 1) / 2 - i; // 确保左半部分和右半部分元素数量相等或左边多一个

            // 边界处理,如果i或j为0或m或n,将边界值设置为极小或极大,以简化边界情况的处理
            int nums_im1 = (i == 0 ? Integer.MIN_VALUE : nums1[i - 1]);
            int nums_i = (i == m ? Integer.MAX_VALUE : nums1[i]);
            int nums_jm1 = (j == 0 ? Integer.MIN_VALUE : nums2[j - 1]);
            int nums_j = (j == n ? Integer.MAX_VALUE : nums2[j]);

            // 检查是否找到了正确的分割线,即nums1[i-1] <= nums2[j]且nums2[j-1] <= nums1[i]
            if (nums_im1 <= nums_j) {
                median1 = Math.max(nums_im1, nums_jm1); // 左半部分的最大值
                median2 = Math.min(nums_i, nums_j); // 右半部分的最小值
                left = i + 1; // 移动左边界
            } else {
                right = i - 1; // 移动右边界
            }
        }

        // 如果m + n是奇数,则返回median1;如果是偶数,则返回两个中值的平均数
        return (m + n) % 2 == 0 ? (median1 + median2) / 2.0 : median1;
    }
}

21. Merge Two Sorted Lists

Easy

You are given the heads of two sorted linked lists list1 and list2.

Merge the two lists into one sorted list. The list should be made by splicing together the nodes of the first two lists.

Return the head of the merged linked list.

class Solution {
    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
        // 创建一个虚拟头节点,这样可以方便地添加元素并最后返回合并后的链表
        ListNode dummyHead = new ListNode(-1);
        ListNode n = dummyHead;

        // 遍历两个链表,直到至少有一个链表被完全遍历
        while (list1 != null && list2 != null) {
            // 比较当前两个链表的头节点,选择较小的节点加入到新链表中
            if (list1.val < list2.val) {
                n.next = list1;
                list1 = list1.next; // 移动 list1
            } else {
                n.next = list2;
                list2 = list2.next; // 移动 list2
            }
            n = n.next; // 移动新链表的指针
        }

        // 如果 list1 还有剩余,将剩余部分全部加到新链表的末尾
        if (list1 != null) {
            n.next = list1;
        }
        // 如果 list2 还有剩余,将剩余部分全部加到新链表的末尾
        if (list2 != null) {
            n.next = list2;
        }

        // 返回合并后的链表的起始位置,即虚拟头节点的下一个节点
        return dummyHead.next;
    }
}

33. Search in Rotated Sorted Array

Medium

There is an integer array nums sorted in ascending order (with distinct values).

Prior to being passed to your function, nums is possibly rotated at an unknown pivot index k (1 <= k < nums.length) such that the resulting array is [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]] (0-indexed). For example, [0,1,2,4,5,6,7] might be rotated at pivot index 3 and become [4,5,6,7,0,1,2].

Given the array nums after the possible rotation and an integer target, return the index of target if it is in nums, or -1 if it is not in nums.

You must write an algorithm with O(log n) runtime complexity.

class Solution {
    public int search(int[] nums, int target) {
        int n = nums.length;
        // 当数组为空时,返回 -1
        if (n == 0) {
            return -1;
        }
        // 如果数组只有一个元素,直接判断该元素是否是目标值
        if (n == 1) {
            return nums[0] == target ? 0 : -1;
        }
        
        int l = 0, r = n - 1;
        // 使用二分查找
        while (l <= r) {
            int mid = (l + r) / 2;
            // 如果找到目标值,返回其索引
            if (nums[mid] == target) {
                return mid;
            }
            
            // 确定旋转的位置,并进行逻辑分割
            if (nums[0] <= nums[mid]) {
                // 情况1: 左半部分是有序的
                if (nums[0] <= target && target < nums[mid]) {
                    // 如果目标值在左半部分,调整右边界
                    r = mid - 1;
                } else {
                    // 否则调整左边界
                    l = mid + 1;
                }
            } else {
                // 情况2: 右半部分是有序的
                if (nums[mid] < target && target <= nums[n - 1]) {
                    // 如果目标值在右半部分,调整左边界
                    l = mid + 1;
                } else {
                    // 否则调整右边界
                    r = mid - 1;
                }
            }
        }
        // 如果循环结束还没有找到,返回 -1
        return -1;
    }
}

55. Jump Game

Medium

You are given an integer array nums. You are initially positioned at the array's first index, and each element in the array represents your maximum jump length at that position.

Return true if you can reach the last index, or false otherwise.

class Solution {
    public boolean canJump(int[] nums) {
        if (nums.length == 1) {
            return true;
        }
        int coverage = 0;//i为0,nums[i]为0的时候,哪也跳不了,coverage表示能跳到位置的下标
        for (int i = 0; i <= coverage; i++) {//判断要写在循环内,因为coverage可能会超过nums.length
            coverage = Math.max(coverage, i + nums[i]);
            if (coverage >= nums.length - 1) {
                return true;
            }
        }
        return false;
    }
}

27. Remove Element

Easy

Given an integer array nums and an integer val, remove all occurrences of val in nums in-place. The order of the elements may be changed. Then return the number of elements in nums which are not equal to val.

Consider the number of elements in nums which are not equal to val be k, to get accepted, you need to do the following things:

  • Change the array nums such that the first k elements of nums contain the elements which are not equal to val. The remaining elements of nums are not important as well as the size of nums.
  • Return k.
class Solution {
    public int removeElement(int[] nums, int val) {
        int slow = 0;
        int fast = 0;
        for(fast = 0; fast < nums.length; fast++){
            if(nums[fast] != val){
                nums[slow] = nums[fast];
                slow++;
            }
        }
        return slow;
    }
}

560. Subarray Sum Equals K

Medium

Given an array of integers nums and an integer k, return the total number of subarrays whose sum equals to k.

A subarray is a contiguous non-empty sequence of elements within an array.

public class Solution {
    public int subarraySum(int[] nums, int k) {
        int count = 0; // 用于计数,符合条件的子数组数量
        int pre = 0; // 用于存储前缀和
        HashMap<Integer, Integer> mp = new HashMap<>(); // 哈希表用于存储前缀和及其出现的次数
        mp.put(0, 1); // 初始化,表示前缀和为0的情况出现一次(考虑从数组开始到当前位置的子数组)

        for (int i = 0; i < nums.length; i++) {
            pre += nums[i]; // 更新当前的前缀和
            
            // 检查当前前缀和与k的差值是否已经在哈希表中
            // 如果在,说明存在一个子数组的和为k
            if (mp.containsKey(pre - k)) {
                count += mp.get(pre - k); // 累加满足条件的子数组的数量
            }
            
            // 更新哈希表,记录当前前缀和的出现次数
            mp.put(pre, mp.getOrDefault(pre, 0) + 1);
        }
        return count; // 返回总的满足条件的子数组的数量
    }
}

11. Container With Most Water

Medium

You are given an integer array height of length n. There are n vertical lines drawn such that the two endpoints of the ith line are (i, 0) and (i, height[i]).

Find two lines that together with the x-axis form a container, such that the container contains the most water.

Return the maximum amount of water a container can store.

Notice that you may not slant the container.

class Solution {
    public int maxArea(int[] height) {
        int left = 0;
        int right = height.length -1;
        int max = 0;
        while(left < right){
            max = Math.max(max, Math.min(height[left], height[right]) * (right - left));
            if(height[left] <= height[right]){
                left++;
            }else{
                right--;
            }
        }
        return max;
    }
}

20. Valid Parentheses

Easy

Given a string s containing just the characters '('')''{''}''[' and ']', determine if the input string is valid.

An input string is valid if:

  1. Open brackets must be closed by the same type of brackets.
  2. Open brackets must be closed in the correct order.
  3. Every close bracket has a corresponding open bracket of the same type.

Example 1:

Input: s = "()"
Output: true
class Solution {
    public boolean isValid(String s) {
        Stack<Character> stack = new Stack<>(); // 使用栈来处理匹配问题
        
        for (char x : s.toCharArray()) { // 遍历字符串的每一个字符
            if (x == '(') { // 如果是开括号 '('
                stack.push(')'); // 则压入相应的闭括号 ')'
            } else if (x == '{') { // 如果是开括号 '{'
                stack.push('}'); // 则压入相应的闭括号 '}'
            } else if (x == '[') { // 如果是开括号 '['
                stack.push(']'); // 则压入相应的闭括号 ']'
            } else if (stack.isEmpty() || stack.pop() != x) { // 如果栈为空或者栈顶元素不匹配当前字符
                return false; // 则字符串无效
            }
        }
        return stack.isEmpty(); // 如果栈为空,说明所有括号都正确匹配
    }
}
class Solution {
    public boolean isValid(String s) {
         Deque<Character> stack = new ArrayDeque<>();
    for (int i = 0; i < s.length(); i++) {
        Character ch = s.charAt(i);
        if (ch == '(') {
            stack.push(')');
        } else if (ch == '[') {
            stack.push(']');
        } else if (ch == '{') {
            stack.push('}');
        } else if (ch == stack.peek()) {
            stack.pop();
        } else {
            return false;
        }
    }
    return stack.isEmpty();
    }
}

31. Next Permutation(可看用户题解)

Medium

permutation of an array of integers is an arrangement of its members into a sequence or linear order.

  • For example, for arr = [1,2,3], the following are all the permutations of arr[1,2,3], [1,3,2], [2, 1, 3], [2, 3, 1], [3,1,2], [3,2,1].

The next permutation of an array of integers is the next lexicographically greater permutation of its integer. More formally, if all the permutations of the array are sorted in one container according to their lexicographical order, then the next permutation of that array is the permutation that follows it in the sorted container. If such arrangement is not possible, the array must be rearranged as the lowest possible order (i.e., sorted in ascending order).

  • For example, the next permutation of arr = [1,2,3] is [1,3,2].
  • Similarly, the next permutation of arr = [2,3,1] is [3,1,2].
  • While the next permutation of arr = [3,2,1] is [1,2,3] because [3,2,1] does not have a lexicographical larger rearrangement.

Given an array of integers numsfind the next permutation of nums.

The replacement must be in place and use only constant extra memory.

class Solution {
    public void nextPermutation(int[] nums) {
        // 从后往前查找第一对连续的、第一个数比第二个数小的位置
        int i = nums.length - 2;
        while (i >= 0 && nums[i] >= nums[i + 1]) {
            i--;
        }
        if (i >= 0) {
            // 如果找到这样的位置,再从数组末尾往前找到第一个比nums[i]大的数
            int j = nums.length - 1;
            while (j >= 0 && nums[i] >= nums[j]) {
                j--;
            }
            // 交换nums[i]和nums[j]
            swap(nums, i, j);
        }
        // 从i+1位置开始到数组末尾进行反转,使其变为字典序最小的排列
        reverse(nums, i + 1);
    }

    // 用于交换数组中两个位置的值
    public void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }

    // 用于反转数组从start到末尾的部分
    public void reverse(int[] nums, int start) {
        int left = start, right = nums.length - 1;
        while (left < right) {
            swap(nums, left, right);
            left++;
            right--;
        }
    }
}

53. Maximum Subarray

Medium

Given an integer array nums, find the 

subarray

 with the largest sum, and return its sum.

class Solution {
    public int maxSubArray(int[] nums) {
        if (nums.length == 1){
            return nums[0];
        }
        int sum = Integer.MIN_VALUE;
        int count = 0;
        for (int i = 0; i < nums.length; i++){
            count += nums[i];
            sum = Math.max(sum, count); // 取区间累计的最大值(相当于不断确定最大子序终止位置)
            if (count <= 0){
                count = 0; // 相当于重置最大子序起始位置,因为遇到负数一定是拉低总和
            }
        }
       return sum;
    }
}

236. Lowest Common Ancestor of a Binary Tree

Solved

Medium

Topics

Companies

Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree.

According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes p and q as the lowest node in T that has both p and q as descendants (where we allow a node to be a descendant of itself).”

Example 1:

Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
Output: 3
Explanation: The LCA of nodes 5 and 1 is 3.
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root == null || root == p || root == q) { // 递归结束条件
            return root;
        }

        // 后序遍历
        TreeNode left = lowestCommonAncestor(root.left, p, q);
        TreeNode right = lowestCommonAncestor(root.right, p, q);

        if(left == null && right == null) { // 若未找到节点 p 或 q
            return null;
        }else if(left == null && right != null) { // 若找到一个节点
            return right;
        }else if(left != null && right == null) { // 若找到一个节点
            return left;
        }else { // 若找到两个节点
            return root;
        }
    }
}

300. Longest Increasing Subsequence

Medium

Topics

Companies

Given an integer array nums, return the length of the longest strictly increasing 

subsequence

.

// Dynamic programming + Dichotomy.
class Solution {
    public int lengthOfLIS(int[] nums) {
        int[] tails = new int[nums.length]; // tails数组用于存储潜在递增子序列的最小尾部
        int res = 0; // 用于记录当前最长递增子序列的长度

        for (int num : nums) { // 遍历每个数字
            int i = 0, j = res; // i和j用于二分搜索的起始和结束索引
            // 二分搜索,寻找tails中第一个不小于num的位置
            while (i < j) {
                int m = (i + j) / 2; // 计算中间索引
                if (tails[m] < num) i = m + 1; // 如果中间值小于num,搜索右半部
                else j = m; // 否则搜索左半
class Solution {
    public int lengthOfLIS(int[] nums) {
        int len = 1, n = nums.length; // len 表示当前最长递增子序列的长度,初始化为 1
        if (n == 0) {
            return 0; // 如果数组为空,返回 0
        }
        int[] d = new int[n + 1]; // d 数组用来存储最长递增子序列的值
        d[len] = nums[0]; // 初始化 d 数组的第一个值为 nums 的第一个元素

        for (int i = 1; i < n; ++i) { // 遍历 nums 数组
            if (nums[i] > d[len]) { // 如果当前元素比 d 数组中的最后一个元素大
                d[++len] = nums[i]; // 增长当前的最长递增子序列长度,并添加这个元素
            } else { // 如果当前元素不大于 d 数组中的最后一个元素
                int l = 1, r = len, pos = 0; // 二分搜索在 d 中找到小于 nums[i] 的最大元素
                // 二分搜索过程
                while (l <= r) {
                    int mid = (l + r) >> 1;
                    if (d[mid] < nums[i]) {
                        pos = mid; // 记录最后一个小于 nums[i] 的位置
                        l = mid + 1; // 继续在右半边搜索
                    } else {
                        r = mid - 1; // 继续在左半边搜索
                    }
                }
                d[pos + 1] = nums[i]; // 更新位置 pos+1 的元素为 nums[i]
            }
        }
        return len; // 返回最长递增子序列的长度
    }
}

26. Remove Duplicates from Sorted Array

Easy

Given an integer array nums sorted in non-decreasing order, remove the duplicates in-place such that each unique element appears only once. The relative order of the elements should be kept the same. Then return the number of unique elements in nums.

Consider the number of unique elements of nums to be k, to get accepted, you need to do the following things:

  • Change the array nums such that the first k elements of nums contain the unique elements in the order they were present in nums initially. The remaining elements of nums are not important as well as the size of nums.
  • Return k.
class Solution {
    public int removeDuplicates(int[] nums) {
        int slow = 1;
        for(int fast = 1; fast < nums.length; fast++){
            if(nums[fast] != nums[fast-1]){
                nums[slow] = nums[fast];
                slow++;
            }
        }
        return slow;
    }
}

215. Kth Largest Element in an Array

Medium

Topics

Companies

Given an integer array nums and an integer k, return the kth largest element in the array.

Note that it is the kth largest element in the sorted order, not the kth distinct element.

Can you solve it without sorting?

Example 1:

Input: nums = [3,2,1,5,6,4], k = 2
Output: 5
class Solution {
    /**
     * 使用快速选择算法寻找第k小的元素
     * @param nums 数组
     * @param l 左边界
     * @param r 右边界
     * @param k 目标位置
     * @return 返回第k小的元素
     */
    int quickselect(int[] nums, int l, int r, int k) {
        if (l == r) return nums[k]; // 当范围缩小到一个元素时,直接返回该元素

        int x = nums[l], i = l - 1, j = r + 1; // 以左边第一个元素为基准,初始化指针
        while (i < j) {
            do i++; while (nums[i] < x); // 从左向右找第一个大于或等于基准的元素
            do j--; while (nums[j] > x); // 从右向左找第一个小于或等于基准的元素
            if (i < j) { // 如果两个指针没有相遇,交换两个元素
                int tmp = nums[i];
                nums[i] = nums[j];
                nums[j] = tmp;
            }
        }
        // 分治递归
        if (k <= j) return quickselect(nums, l, j, k); // 如果k在左侧,递归左半边
        else return quickselect(nums, j + 1, r, k); // 否则递归右半边
    }

    /**
     * 寻找第k大的元素
     * @param _nums 输入的数组
     * @param k 第k大的序号
     * @return 返回第k大的元素
     */
    public int findKthLargest(int[] _nums, int k) {
        int n = _nums.length; // 数组长度
        // 由于quickselect是找第k小的元素,所以用长度减去k得到第k大的元素的索引
        return quickselect(_nums, 0, n - 1, n - k);
    }
}
class Solution {
    public int findKthLargest(int[] nums, int k) {
        int heapSize = nums.length;
        buildMaxHeap(nums, heapSize); // 构建最大堆
        // 移除堆顶元素,即最大元素,总共移除 k-1 次
        for (int i = nums.length - 1; i >= nums.length - k + 1; --i) {
            swap(nums, 0, i); // 将最大元素(堆顶元素)与数组末尾的元素交换
            --heapSize; // 堆大小减小
            maxHeapify(nums, 0, heapSize); // 重新调整堆
        }
        return nums[0]; // 返回第 k 大的元素,此时位于堆顶
    }

    // 构建最大堆
    public void buildMaxHeap(int[] a, int heapSize) {
        // 从最后一个非叶子节点开始,向前调整所有非叶子节点
        for (int i = heapSize / 2; i >= 0; --i) {
            maxHeapify(a, i, heapSize);
        } 
    }

    // 最大堆的调整函数
    public void maxHeapify(int[] a, int i, int heapSize) {
        int l = i * 2 + 1; // 左子节点索引
        int r = i * 2 + 2; // 右子节点索引
        int largest = i; // 假设当前节点是最大的

        // 如果左子节点更大,更新最大值索引
        if (l < heapSize && a[l] > a[largest]) {
            largest = l;
        } 
        // 如果右子节点更大,更新最大值索引
        if (r < heapSize && a[r] > a[largest]) {
            largest = r;
        }
        // 如果最大值索引不是当前节点,交换并继续调整
        if (largest != i) {
            swap(a, i, largest);
            maxHeapify(a, largest, heapSize);
        }
    }

    // 交换数组中的两个元素
    public void swap(int[] a, int i, int j) {
        int temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }
}

279. Perfect Squares

Solved

Medium

Topics

Companies

Given an integer n, return the least number of perfect square numbers that sum to n.

perfect square is an integer that is the square of an integer; in other words, it is the product of some integer with itself. For example, 149, and 16 are perfect squares while 3 and 11 are not.

Example 1:

Input: n = 12
Output: 3
Explanation: 12 = 4 + 4 + 4.
class Solution {
    public int numSquares(int n) {
        int[] f = new int[n + 1]; // f[i] 存储和为i的最少的完全平方数的个数
        // 初始化动态规划数组
        for (int i = 1; i <= n; i++) {
            int minn = Integer.MAX_VALUE; // 初始化最小值为非常大的数,以便进行最小值比较
            // 遍历所有可能的完全平方数
            for (int j = 1; j * j <= i; j++) {
                minn = Math.min(minn, f[i - j * j]); // 寻找最小的f[i - j*j],j*j是一个完全平方数
            }
            f[i] = minn + 1; // 当前i的最少平方数等于找到的最小值加1
        }
        return f[n]; // 返回和为n的最少的完全平方数的个数
    }
}

438. Find All Anagrams in a String

Medium

Topics

Companies

Given two strings s and p, return an array of all the start indices of p's anagrams in s. You may return the answer in any order.

An Anagram is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.

Example 1:

Input: s = "cbaebabacd", p = "abc"
Output: [0,6]
Explanation:
The substring with start index = 0 is "cba", which is an anagram of "abc".
The substring with start index = 6 is "bac", which is an anagram of "abc".
class Solution {
    public List<Integer> findAnagrams(String s, String p) {
        int sLen = s.length(), pLen = p.length();

        // 如果 s 的长度小于 p 的长度,不可能有字母异位词
        if (sLen < pLen) {
            return new ArrayList<Integer>();
        }

        List<Integer> ans = new ArrayList<Integer>(); // 存储所有异位词的起始索引
        int[] sCount = new int[26]; // s 的字符频率计数
        int[] pCount = new int[26]; // p 的字符频率计数

        // 初始化计数数组
        for (int i = 0; i < pLen; ++i) {
            ++sCount[s.charAt(i) - 'a'];
            ++pCount[p.charAt(i) - 'a'];
        }

        // 检查初始窗口是否是异位词
        if (Arrays.equals(sCount, pCount)) {
            ans.add(0);
        }

        // 使用滑动窗口遍历 s 中的每个子串
        for (int i = 0; i < sLen - pLen; ++i) {
            --sCount[s.charAt(i) - 'a']; // 移除窗口最左边的字符
            ++sCount[s.charAt(i + pLen) - 'a']; // 添加新的字符到窗口

            // 检查更新后的窗口是否是异位词
            if (Arrays.equals(sCount, pCount)) {
                ans.add(i + 1); // 如果是,添加当前窗口的起始索引到结果列表
            }
        }

        return ans; // 返回结果
    }
}

135. Candy

Hard

There are n children standing in a line. Each child is assigned a rating value given in the integer array ratings.

You are giving candies to these children subjected to the following requirements:

  • Each child must have at least one candy.
  • Children with a higher rating get more candies than their neighbors.

Return the minimum number of candies you need to have to distribute the candies to the children.

class Solution {
    public int candy(int[] ratings) {
        // 如果只有一个学生,直接返回1颗糖果
        if (ratings.length == 1) {
            return 1;
        }
        int[] candy = new int[ratings.length]; // 糖果分配数组
        candy[0] = 1; // 第一个学生至少得到1颗糖果

        // 从左向右遍历,保证每个学生如果评分比左边学生高,则糖果数比左边学生多
        for (int i = 1; i < ratings.length; i++) {
            if (ratings[i] > ratings[i - 1]) {
                candy[i] = candy[i - 1] + 1; // 如果当前学生评分高于前一个,糖果数为前一个学生的糖果数加1
            } else {
                candy[i] = 1; // 否则,至少得到1颗糖果
            }
        }

        // 从右向左遍历,保证每个学生如果评分比右边学生高,则糖果数比右边学生多
        for (int i = ratings.length - 2; i >= 0; i--) {
            if (ratings[i] > ratings[i + 1]) {
                candy[i] = Math.max(candy[i], candy[i + 1] + 1); // 保证如果当前学生评分高于后一个,则至少比后一个学生多1颗糖果
            }
        }

        int ans = 0; // 总糖果数
        for (int i = 0; i < candy.length; i++) {
            ans += candy[i]; // 累加所有糖果数
        }
        return ans; // 返回总糖果数
    }
}

148. Sort List

Medium

Given the head of a linked list, return the list after sorting it in ascending order.

class Solution {
    // 公共接口,初始化排序
    public ListNode sortList(ListNode head) {
        return sortList(head, null);
    }

    // 排序函数,使用归并排序
    public ListNode sortList(ListNode head, ListNode tail) {
        if (head == null) {
            return head;
        }
        if (head.next == tail) {  // 当头结点的下一个节点是尾节点时,断开并返回头结点
            head.next = null;     // 断开链表
            return head;
        }
        ListNode slow = head, fast = head;
        // 使用快慢指针找到中间节点
        while (fast != tail) {
            slow = slow.next;
            fast = fast.next;
            if (fast != tail) {
                fast = fast.next;
            }
        }
        ListNode mid = slow;
        // 递归排序前半部分
        ListNode list1 = sortList(head, mid);
        // 递归排序后半部分
        ListNode list2 = sortList(mid, tail);
        // 合并两个排序好的链表
        ListNode sorted = merge(list1, list2);
        return sorted;
    }

    // 合并两个已排序的链表
    public ListNode merge(ListNode head1, ListNode head2) {
        ListNode dummyHead = new ListNode(0); // 虚拟头结点,便于操作
        ListNode temp = dummyHead, temp1 = head1, temp2 = head2;
        while (temp1 != null && temp2 != null) {
            if (temp1.val <= temp2.val) { // 比较两链表头部值的大小,较小者接到结果链表
                temp.next = temp1;
                temp1 = temp1.next;
            } else {
                temp.next = temp2;
                temp2 = temp2.next;
            }
            temp = temp.next;
        }
        // 将未结束的链表接到结果链表的尾部
        if (temp1 != null) {
            temp.next = temp1;
        } else if (temp2 != null) {
            temp.next = temp2;
        }
        return dummyHead.next; // 返回排序后的链表头结点
    }
}

9. Palindrome Number

Easy

Given an integer x, return true if x is a palindrome, and false otherwise.

class Solution {
    public boolean isPalindrome(int x) {
        // 特殊情况:
        // 如上所述,当 x < 0 时,x 不是回文数。
        // 同样地,如果数字的最后一位是 0,为了使该数字为回文,
        // 则其第一位数字也应该是 0
        // 只有 0 满足这一属性
        if (x < 0 || (x % 10 == 0 && x != 0)) {
            return false;
        }

        int revertedNumber = 0;
        while (x > revertedNumber) {
            revertedNumber = revertedNumber * 10 + x % 10;
            x /= 10;
        }

        // 当数字长度为奇数时,我们可以通过 revertedNumber/10 去除处于中位的数字。
        // 例如,当输入为 12321 时,在 while 循环的末尾我们可以得到 x = 12,revertedNumber = 123,
        // 由于处于中位的数字不影响回文(它总是与自己相等),所以我们可以简单地将其去除。
        return x == revertedNumber || x == revertedNumber / 10;
    }
}

169. Majority Element

Easy

Given an array nums of size n, return the majority element.

The majority element is the element that appears more than ⌊n / 2⌋ times. You may assume that the majority element always exists in the array.

Example 1:

Input: nums = [3,2,3]
Output: 3
class Solution {
    // 公共接口,开始寻找多数元素
    public int majorityElement(int[] nums) {
        int val = MajorityElement(nums, nums[0], 0);
        return val;
    }

    // 递归函数,实现摩尔投票算法
    public int MajorityElement(int[] nums, int val, int index) {
        int count = 0; // 初始化计数器
        for (int i = index; i < nums.length; i++) {
            if (nums[i] == val) {
                count++; // 如果当前元素等于候选元素,计数器增加
            } else {
                count--; // 否则,计数器减少
            }
            if (count < 0) {
                // 如果计数器小于0,说明当前候选元素不可能是多数元素
                return MajorityElement(nums, nums[i], i); // 从当前位置递归寻找新的候选元素
            }
        }
        return val; // 返回候选元素,最终确认为多数元素
    }
}
class Solution {
    // 辅助方法,用于计数数组中每个元素的出现次数
    private Map<Integer, Integer> countNums(int[] nums) {
        Map<Integer, Integer> counts = new HashMap<>(); // 创建哈希表来存储每个数字及其出现的次数
        for (int num : nums) {
            // 如果数字未在哈希表中,初始化其计数为1
            if (!counts.containsKey(num)) {
                counts.put(num, 1);
            } else {
                // 如果数字已存在,增加其计数
                counts.put(num, counts.get(num) + 1);
            }
        }
        return counts; // 返回包含所有数字及其出现次数的哈希表
    }

    // 主方法,返回数组中的多数元素
    public int majorityElement(int[] nums) {
        Map<Integer, Integer> counts = countNums(nums); // 获取数字及其出现次数的映射

        Map.Entry<Integer, Integer> majorityEntry = null; // 用于记录出现次数最多的元素
        for (Map.Entry<Integer, Integer> entry : counts.entrySet()) {
            // 初始化或更新记录最多次数的元素
            if (majorityEntry == null || entry.getValue() > majorityEntry.getValue()) {
                majorityEntry = entry;
            }
        }

        return majorityEntry.getKey(); // 返回出现次数最多的元素的键
    }
}

76. Minimum Window Substring

Hard

Given two strings s and t of lengths m and n respectively, return the minimum window 

substring

 of s such that every character in t (including duplicates) is included in the window. If there is no such substring, return the empty string "".

The testcases will be generated such that the answer is unique.

Example 1:

Input: s = "ADOBECODEBANC", t = "ABC"
Output: "BANC"
Explanation: The minimum window substring "BANC" includes 'A', 'B', and 'C' from string t.
class Solution {
    public String minWindow(String s, String t) {
        // 验证输入有效性
        if (s == null || t == null || s.length() == 0 || t.length() == 0 || s.length() < t.length()) {
            return new String();  // 如果不合理,返回空字符串
        }

        int[] map = new int[128]; // 创建一个ASCII大小的数组来存储字符计数
        int count = t.length();  // 需要匹配的字符总数
        int start = 0, end = 0;  // 初始化滑动窗口的起始和结束指针
        int minLen = Integer.MAX_VALUE, startIndex = 0;  // 用于记录最小子串的长度和起始索引

        // 将字符串t中的字符计数到map中
        for (char c : t.toCharArray()) {
            map[c]++;
        }

        char[] chS = s.toCharArray();  // 将字符串s转换为字符数组,以便更快地处理
        // 扩大窗口,直到窗口包含所有t的字符
        while (end < chS.length) {
            // 如果当前字符是t中的字符,则减少计数
            if (map[chS[end++]]-- > 0) {
                count--;
            }
            // 当找到有效窗口,包含所有t的字符时
            while (count == 0) {
                // 更新最小子串的长度和起始索引
                if (end - start < minLen) {
                    startIndex = start;
                    minLen = end - start;
                }
                // 尝试缩小窗口,如果当前字符是t中的字符,增加计数
                if (map[chS[start++]]++ == 0) {
                    count++;
                }
            }
        }

        // 如果找到了有效的最小窗口,则返回这个窗口子串;否则返回空字符串
        return minLen == Integer.MAX_VALUE ? new String() : new String(chS, startIndex, minLen);
    }
}
class Solution {
    Map<Character, Integer> ori = new HashMap<Character, Integer>(); // 原始字符计数
    Map<Character, Integer> cnt = new HashMap<Character, Integer>(); // 窗口字符计数

    public String minWindow(String s, String t) {
        int tLen = t.length();
        // 初始化原始字符计数
        for (int i = 0; i < tLen; i++) {
            char c = t.charAt(i);
            ori.put(c, ori.getOrDefault(c, 0) + 1);
        }

        int l = 0, r = -1; // 初始化滑动窗口的左右指针
        int len = Integer.MAX_VALUE, ansL = -1, ansR = -1; // 存储最小窗口的大小和起始位置
        int sLen = s.length();
        // 扩展窗口的右边界
        while (r < sLen) {
            ++r;
            if (r < sLen && ori.containsKey(s.charAt(r))) {
                cnt.put(s.charAt(r), cnt.getOrDefault(s.charAt(r), 0) + 1);
            }
            // 检查当前窗口是否包含所有t的字符
            while (check() && l <= r) {
                if (r - l + 1 < len) { // 更新最小窗口
                    len = r - l + 1;
                    ansL = l;
                    ansR = l + len;
                }
                // 收缩窗口的左边界
                if (ori.containsKey(s.charAt(l))) {
                    cnt.put(s.charAt(l), cnt.getOrDefault(s.charAt(l), 0) - 1);
                }
                ++l;
            }
        }
        // 返回最小窗口子串或空字符串
        return ansL == -1 ? "" : s.substring(ansL, ansR);
    }

    // 辅助函数,检查窗口内的字符是否满足包含所有t的字符的要求
    public boolean check() {
        Iterator iter = ori.entrySet().iterator(); 
        while (iter.hasNext()) { 
            Map.Entry entry = (Map.Entry) iter.next(); 
            Character key = (Character) entry.getKey(); 
            Integer val = (Integer) entry.getValue(); 
            // 如果窗口中某个字符的数量小于t中该字符的数量,返回false
            if (cnt.getOrDefault(key, 0) < val) {
                return false;
            }
        } 
        return true; // 窗口满足条件
    }
}

22. Generate Parentheses

Medium

Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.

class Solution {
    public List<String> generateParenthesis(int n) {
        List<String> ans = new ArrayList<String>(); // 结果列表,用来存储所有有效的括号组合
        backtrack(ans, new StringBuilder(), 0, 0, n); // 调用回溯方法开始生成括号
        return ans; // 返回生成的所有有效括号组合
    }

    // 回溯方法
    public void backtrack(List<String> ans, StringBuilder cur, int open, int close, int max) {
        if (cur.length() == max * 2) { // 如果当前字符串长度等于2*n,表示形成了一个有效的组合
            ans.add(cur.toString()); // 将当前组合添加到结果列表中
            return; // 返回上一层递归
        }
        if (open < max) { // 如果“开括号”数量小于n,可以添加一个“开括号”
            cur.append('('); // 添加一个“开括号”
            backtrack(ans, cur, open + 1, close, max); // 递归调用,进入下一层
            cur.deleteCharAt(cur.length() - 1); // 回溯,删除刚才添加的“开括号”
        }
        if (close < open) { // 如果“闭括号”数量小于“开括号”数量,可以添加一个“闭括号”
            cur.append(')'); // 添加一个“闭括号”
            backtrack(ans, cur, open, close + 1, max); // 递归调用,进入下一层
            cur.deleteCharAt(cur.length() - 1); // 回溯,删除刚才添加的“闭括号”
        }
    }
}

101. Symmetric Tree

Easy

Given the root of a binary tree, check whether it is a mirror of itself (i.e., symmetric around its center).

class Solution {
    public boolean isSymmetric(TreeNode root) {
        return compare(root.left, root.right);
    }

    private boolean compare(TreeNode left, TreeNode right) {
        if (left == null && right == null) {
            return true;
        }
        if (left == null || right == null) {
            return false;
        }
        if (left.val != right.val) {
            return false;
        }
        return compare(left.right, right.left) && compare(left.left, right.right);
    }
}

14. Longest Common Prefix

Solved

Easy

Topics

Companies

Write a function to find the longest common prefix string amongst an array of strings.

If there is no common prefix, return an empty string "".

Example 1:

Input: strs = ["flower","flow","flight"]
Output: "fl"
class Solution {
    public String longestCommonPrefix(String[] strs) {
        if (strs.length == 0)  // 如果数组为空,则直接返回空字符串
            return "";
        String ans = strs[0]; // 初始假设第一个字符串为最长公共前缀

        for (int i = 1; i < strs.length; i++) { // 遍历每一个字符串
            int j = 0;
            // 比较当前最长公共前缀ans与当前字符串的每个字符
            for (; j < ans.length() && j < strs[i].length(); j++) {
                if (ans.charAt(j) != strs[i].charAt(j)) // 一旦发现字符不匹配
                    break; // 停止该字符串的比较
            }
            ans = ans.substring(0, j); // 更新最长公共前缀
            if (ans.equals("")) // 如果公共前缀为空,则无需继续检查
                return ans;
        }
        return ans; // 返回最长公共前缀
    }
}

54. Spiral Matrix

Medium

Given an m x n matrix, return all elements of the matrix in spiral order.

class Solution {
    public List<Integer> spiralOrder(int[][] matrix) {
         List<Integer> ans = new ArrayList<>();
        int m = matrix.length;
        int n = matrix[0].length;
        int l = 0;
        int r = n - 1;
        int t = 0;
        int b = m - 1;
        int count = 1;
        int target = m * n;
        while (count <= target) {
            for (int i = l; i <= r ; i++) { 
                if(count <= target){// 添加检查
                    ans.add(matrix[t][i]);
                    count++;
                }
            }
            t++;
            for (int i = t; i <= b ; i++) { // 添加检查
                if(count <= target){
                    ans.add(matrix[i][r]);
                    count++;}
            }
            r--;
            for (int i = r; i >= l ; i--) { // 添加检查
                if(count <= target){
                    ans.add(matrix[b][i]);
                    count++;
                }
            }
            b--;
            for (int i = b; i >= t ; i--) { // 添加检查
               if(count <= target){
                 ans.add(matrix[i][l]);
                 count++;
               }
            }
            l++;
        }
        return ans;
    }
}

56. Merge Intervals

Medium

Given an array of intervals where intervals[i] = [starti, endi], merge all overlapping intervals, and return an array of the non-overlapping intervals that cover all the intervals in the input.

Example 1:

Input: intervals = [[1,3],[2,6],[8,10],[15,18]]
Output: [[1,6],[8,10],[15,18]]
Explanation: Since intervals [1,3] and [2,6] overlap, merge them into [1,6].
class Solution {
    public int[][] merge(int[][] intervals) {
        LinkedList<int[]> res = new LinkedList<>();
        Arrays.sort(intervals, (o1, o2) -> Integer.compare(o1[0], o2[0]));
        res.add(intervals[0]);
        for (int i = 1; i < intervals.length; i++) {
            if (intervals[i][0] <= res.getLast()[1]) {
                int start = res.getLast()[0];
                int end = Math.max(intervals[i][1], res.getLast()[1]);
                res.removeLast();
                res.add(new int[]{start, end});
            }
            else {
                res.add(intervals[i]);
            }         
        }
        return res.toArray(new int[res.size()][]);
    }
}

72. Edit Distance

Medium

Topics

Companies

Given two strings word1 and word2, return the minimum number of operations required to convert word1 to word2.

You have the following three operations permitted on a word:

  • Insert a character
  • Delete a character
  • Replace a character
class Solution {
    public int minDistance(String word1, String word2) {
        int n1 = word1.length();  // 获取word1的长度
        int n2 = word2.length();  // 获取word2的长度
        int[][] dp = new int[n1 + 1][n2 + 1];  // 创建动态规划表格

        // 初始化第一行:从空字符串到word2的所有前缀的编辑距离,即逐个插入字符
        for (int j = 1; j <= n2; j++) {
            dp[0][j] = dp[0][j - 1] + 1;
        }
        
        // 初始化第一列:从空字符串到word1的所有前缀的编辑距离,即逐个插入字符
        for (int i = 1; i <= n1; i++) {
            dp[i][0] = dp[i - 1][0] + 1;
        }

        // 填充dp表
        for (int i = 1; i <= n1; i++) {
            for (int j = 1; j <= n2; j++) {
                // 如果当前字符相同,则不需要编辑操作,直接继承左上角的值
                if (word1.charAt(i - 1) == word2.charAt(j - 1)) {
                    dp[i][j] = dp[i - 1][j - 1];
                } else {
                    // 如果当前字符不同,取插入、删除或替换操作的最小值加1
                    dp[i][j] = Math.min(Math.min(dp[i - 1][j - 1],  // 替换操作
                                                dp[i][j - 1]),     // 插入操作
                                                dp[i - 1][j])      // 删除操作
                             + 1;
                }
            }
        }
        return dp[n1][n2];  // 返回从word1到word2的最小编辑距离
    }
}

206. Reverse Linked List

Easy

Given the head of a singly linked list, reverse the list, and return the reversed list.

class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode newHead = null;
        ListNode o1 = head;
        while(o1 != null){
            ListNode o2 = o1.next;
            o1.next = newHead;
            newHead = o1;
            o1 = o2;
        }
        return newHead;
    }
}

152. Maximum Product Subarray

Medium

Given an integer array nums, find a subarray that has the largest product, and return the product.

The test cases are generated so that the answer will fit in a 32-bit integer.

Example 1:

Input: nums = [2,3,-2,4]
Output: 6
Explanation: [2,3] has the largest product 6.
class Solution {
    public int maxProduct(int[] nums) {
        int length = nums.length;
        int[] maxF = new int[length];
        int[] minF = new int[length];
        System.arraycopy(nums, 0, maxF, 0, length);
        System.arraycopy(nums, 0, minF, 0, length);
        for (int i = 1; i < length; ++i) {
            maxF[i] = Math.max(maxF[i - 1] * nums[i], Math.max(nums[i], minF[i - 1] * nums[i]));
            minF[i] = Math.min(minF[i - 1] * nums[i], Math.min(nums[i], maxF[i - 1] * nums[i]));
        }
        int ans = maxF[0];
        for (int i = 1; i < length; ++i) {
            ans = Math.max(ans, maxF[i]);
        }
        return ans;
    }
}

80. Remove Duplicates from Sorted Array II

Medium

Topics

Companies

Given an integer array nums sorted in non-decreasing order, remove some duplicates in-place such that each unique element appears at most twice. The relative order of the elements should be kept the same.

Since it is impossible to change the length of the array in some languages, you must instead have the result be placed in the first part of the array nums. More formally, if there are k elements after removing the duplicates, then the first k elements of nums should hold the final result. It does not matter what you leave beyond the first k elements.

Return k after placing the final result in the first k slots of nums.

Do not allocate extra space for another array. You must do this by modifying the input array in-place with O(1) extra memory.

class Solution {
    public int removeDuplicates(int[] nums) {
        int n = nums.length;
        // 如果数组长度不超过2,则所有元素已符合要求,直接返回数组长度
        if (n <= 2) {
            return n;
        }
        // 初始化两个指针,slow从2开始,因为前两个元素允许重复,不需要移动
        int slow = 2, fast = 2;

        // 快指针fast遍历整个数组
        while (fast < n) {
            // 检查当前fast指针的元素是否与slow指针前两个位置的元素不同
            if (nums[slow - 2] != nums[fast]) {
                // 如果不同,说明没有重复超过两次,将fast位置的元素复制到slow位置
                nums[slow] = nums[fast];
                ++slow; // 移动slow指针,为下一个可能的元素预留位置
            }
            ++fast; // 不论是否复制,fast指针总是向前移动
        }
        // 返回新的数组长度,即slow指针的位置
        return slow;
    }
}

39. Combination Sum

Medium

Given an array of distinct integers candidates and a target integer target, return a list of all unique combinations of candidates where the chosen numbers sum to target. You may return the combinations in any order.

The same number may be chosen from candidates an unlimited number of times. Two combinations are unique if the 

frequency

 of at least one of the chosen numbers is different.

The test cases are generated such that the number of unique combinations that sum up to target is less than 150 combinations for the given input.

Example 1:

Input: candidates = [2,3,6,7], target = 7
Output: [[2,2,3],[7]]
Explanation:
2 and 3 are candidates, and 2 + 2 + 3 = 7. Note that 2 can be used multiple times.
7 is a candidate, and 7 = 7.
These are the only two combinations.
class Solution {
    List<List<Integer>> ans = new ArrayList<>(); // 存储最终结果的列表
    List<Integer> path = new ArrayList<>(); // 用于存储当前的组合路径

    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        backTrack(candidates, target, 0); // 从索引0开始回溯
        return ans; // 返回所有找到的组合
    }

    private void backTrack(int[] candidates, int target, int startIndex) {
        if (target < 0) {
            return; // 如果当前目标数小于0,说明当前路径不可行,回退
        }
        if (target == 0) {
            ans.add(new ArrayList<>(path)); // 如果目标数为0,说明找到了有效的组合,将其添加到结果列表中
            return; // 完成当前路径的探索
        }
        for (int i = startIndex; i < candidates.length; i++) { // 遍历候选数组
            path.add(candidates[i]); // 将当前候选加入到路径中
            // 递归调用backTrack,目标数减去当前候选数,从当前的索引开始(允许重复选取当前数字)
            backTrack(candidates, target - candidates[i], i);
            path.remove(path.size() - 1); // 回溯,移除路径中最后一个元素
        }
    }
}

46. Permutations

Medium

Given an array nums of distinct integers, return all the possible permutations. You can return the answer in any order.

class Solution {
    List<List<Integer>> ans = new ArrayList<>();
    List<Integer> path = new ArrayList<>();
    boolean[] used;

    public List<List<Integer>> permute(int[] nums) {
        used = new boolean[nums.length];
        backTrack(nums);
        return ans;
    }

    private void backTrack(int[] nums) {
        if (path.size() == nums.length) {
            ans.add(new ArrayList<>(path));
            return;
        }
        for (int i = 0; i < nums.length; i++) {
            if (used[i] == false) {
                path.add(nums[i]);
                used[i] = true;
                backTrack(nums);
                path.remove(path.size() - 1);
                used[i] = false;
            }
        }
    }
}

62. Unique Paths

Medium

There is a robot on an m x n grid. The robot is initially located at the top-left corner (i.e., grid[0][0]). The robot tries to move to the bottom-right corner (i.e., grid[m - 1][n - 1]). The robot can only move either down or right at any point in time.

Given the two integers m and n, return the number of possible unique paths that the robot can take to reach the bottom-right corner.

The test cases are generated so that the answer will be less than or equal to 2 * 109.

class Solution {
    public int uniquePaths(int m, int n) {
        int[][] dp = new int[m][n];//表示走到[m,n]需要的步数;
        for (int i = 0; i < m; i++) {
            dp[i][0] = 1;//易错,分清楚行和列
        }
        for (int i = 0; i < n; i++) {
            dp[0][i] = 1;
        }
        for (int i = 1; i < m; i++) {
            for (int j = 1; j < n; j++) {
                dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
            }
        }
        return dp[m - 1][n - 1];
    }
}

104. Maximum Depth of Binary Tree

Easy

Given the root of a binary tree, return its maximum depth.

A binary tree's maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.

class Solution {
    public int maxDepth(TreeNode root) {
        if(root == null){
            return 0;
        }
        int leftDepth = maxDepth(root.left);
        int rightDepth = maxDepth(root.right);
        return Math.max(leftDepth , rightDepth) + 1;
    }
}
class Solution {
    public int maxDepth(TreeNode root) {
        int ans = 0;
        if(root==null){
            return ans;
        }
        Deque<TreeNode> queue = new ArrayDeque<>();
        queue.offer(root);
        while(!queue.isEmpty()){
            int n = queue.size();
            while(n>0){
                TreeNode poll = queue.poll();
                if(poll.left!=null){
                    queue.offer(poll.left);
                }
                if(poll.right!=null){
                    queue.offer(poll.right);
                }
                n--;
            }
            ans++;
        }
        return ans;
    }
}

122. Best Time to Buy and Sell Stock II

Medium

You are given an integer array prices where prices[i] is the price of a given stock on the ith day.

On each day, you may decide to buy and/or sell the stock. You can only hold at most one share of the stock at any time. However, you can buy it then immediately sell it on the same day.

Find and return the maximum profit you can achieve.

Example 1:

Input: prices = [7,1,5,3,6,4]
Output: 7
Explanation: Buy on day 2 (price = 1) and sell on day 3 (price = 5), profit = 5-1 = 4.
Then buy on day 4 (price = 3) and sell on day 5 (price = 6), profit = 6-3 = 3.
Total profit is 4 + 3 = 7.
class Solution {
    public int maxProfit(int[] prices) {
        // 如果价格数组只有一个元素,则没有交易的机会,返回利润为0
        if (prices.length == 1) {
            return 0;
        }
        
        int profit = 0;  // 初始化利润为0
        // 遍历价格数组,从第二天开始比较
        for (int i = 1; i < prices.length; i++) {
            // 计算相邻两天的价格差
            int a = prices[i] - prices[i - 1];
            // 如果价格差大于0,表示第i天的价格比前一天高,存在利润
            if (a > 0) {
                profit += a;  // 将这部分利润加到总利润中
            }
        }
        // 返回计算得到的最大利润
        return profit;
    }
}
class Solution {
    public int maxProfit(int[] prices) {
        int n = prices.length;
        int[][] dp = new int[n][2];     // 创建二维数组存储状态
        dp[0][0] = -prices[0];
        dp[0][1] = 0;
        for (int i = 1; i < n; ++i) {
            dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] - prices[i]);    // 第 i 天,持有股票
            dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] + prices[i]);    // 第 i 天,没有股票
        }
        return dp[n - 1][1];  
    }
}

179. Largest Number

Medium

Given a list of non-negative integers nums, arrange them such that they form the largest number and return it.

Since the result may be very large, so you need to return a string instead of an integer.

class Solution {
    public String largestNumber(int[] nums) {
        int n = nums.length; // 数组的长度
        // 将原始的int数组转换成Integer数组,这是为了使用Arrays.sort的Comparator
        Integer[] numsArr = new Integer[n];
        for (int i = 0; i < n; i++) {
            numsArr[i] = nums[i];
        }

        // 自定义排序规则
        Arrays.sort(numsArr, (x, y) -> {
            long sx = 10, sy = 10;
            // 计算10的幂次,sx为x的位数的10的幂次
            while (sx <= x) {
                sx *= 10;
            }
            // 计算10的幂次,sy为y的位数的10的幂次
            while (sy <= y) {
                sy *= 10;
            }
            // 自定义排序规则,这里的规则是比较两个数字拼接的结果 (y+x) 和 (x+y) 的大小
            return (int) (-sy * x - y + sx * y + x);
        });

        // 如果排序后的最大数字是0(即所有数字都是0),直接返回"0"
        if (numsArr[0] == 0) {
            return "0";
        }
        // 使用StringBuilder来构建最终的字符串
        StringBuilder ret = new StringBuilder();
        for (int num : numsArr) {
            ret.append(num);
        }
        // 返回构建好的字符串
        return ret.toString();
    }
}

 完结

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值