Weekly leetcode - 5/NC17/121/122/123/112/309/714/2/415

Keywords: Linux Operation & Maintenance server

leetcode - 5. Longest palindrome substring

Give you a string s and find the longest palindrome substring in S.

Example 1:
Input: s = "babad"
Output:"bab"
Explanation:"aba" The same answer is in line with the meaning of the question.

Example 2:
Input: s = "cbbd"
Output:"bb"

Example 3:
Input: s = "a"
Output:"a"

Example 4:
Input: s = "ac"
Output:"a" 

Solution: dynamic programming
Solution ideas: see my other blog: leetcode questions 1-30

class Solution {
    public String longestPalindrome(String s) {
        if(s==null || s.length()<=0){
            return null;
        }
        boolean[][] dp = new boolean[s.length()][s.length()];
        String res = "";
        int maxLength=0; 
        for(int j=0;j<s.length();j++){
            for(int i=0;i<=j;i++){
                dp[i][j] = (s.charAt(i)==s.charAt(j)) && (j-i<=1 || dp[i+1][j-1]);
                // Description is a palindrome substring
                if(dp[i][j]){
                    if(j-i+1>maxLength){
                        maxLength = j-i+1;
                        res = s.substring(i,j+1);
                    }
                }
            }
        }
        return res;
    }
}

Sword finger offer - NC17 longest palindrome substring

public class Solution {
    /**
     * The class name, method name and parameter name in the code have been specified. Do not modify them. Just return the value specified by the method directly
     *
     * 
     * @param A string character string 
     * @return int integer
     */
    public int getLongestPalindrome (String A) {
        String s = A;
        if(s==null || s.length()<=0){
            return 0;
        }
        boolean[][] dp = new boolean[s.length()][s.length()];
        String res = "";
        int maxLength=0;
        for(int j=0;j<s.length();j++){
            for(int i=0;i<=j;i++){
                dp[i][j] = (s.charAt(i)==s.charAt(j)) && (j-i<=1 || dp[i+1][j-1]);
                // Description is a palindrome substring
                if(dp[i][j]){
                    if(j-i+1>maxLength){
                        maxLength = j-i+1;
                        res = s.substring(i,j+1);
                    }
                }
            }
        }
        return res.length();
    }
}

leetcode - 121. The best time to buy and sell stocks

Given an array of prices, its ith element prices[i] represents the price of a given stock on day I.

You can only choose to buy this stock one day and sell it on a different day in the future. Design an algorithm to calculate the maximum profit you can make.

Return the maximum profit you can make from this transaction. If you can't make any profit, return 0.

Example 1:
Input:[7,1,5,3,6,4]
Output: 5
 Explanation: on day 2 (stock price) = 1)When buying, on day 5 (stock price) = 6)When you sell, you make the most profit = 6-1 = 5 . 
     Note that the profit cannot be 7-1 = 6, Because the selling price needs to be greater than the buying price; at the same time, you can't sell stocks before buying.
     
Example 2:
Input: prices = [7,6,4,3,1]
Output: 0
 Explanation: in this case, No transaction completed, So the maximum profit is 0.

Method 1: violent solution

class Solution {
    public int maxProfit(int[] prices) {
        // When the following number is larger than the previous one, find the maximum difference between the two numbers
        if(prices==null || prices.length<=0){
            return 0;
        }
        int maxProfile = 0;
        for(int i=0;i<prices.length;i++){
            for(int j=i+1;j<prices.length;j++){
                if(prices[i]<=prices[j]){
                    maxProfile = Math.max(maxProfile,prices[j]-prices[i]);
                }
            }
        }
        return maxProfile;
    }
}

Method 2: dynamic programming

class Solution {
    public int maxProfit(int[] prices) {
        // When the following number is larger than the previous one, find the maximum difference between the two numbers
        if(prices==null || prices.length==0){
            return 0;
        }
        // Dynamic programming: dp[i][j] represents the maximum profit obtained on day I, I represents day I, and j represents whether to hold shares
        // j has two states: j=0 means not holding stocks (supports one-time buying and one-time selling, and does not support multiple buying and selling)
        // j=1 means holding shares
        int[][] dp = new int[prices.length][2];
        // No shares held on day 1
        dp[0][0] = 0;
        // Day 1 shares held
        dp[0][1] = -prices[0];
        for(int i=1;i<prices.length;i++){
            // On behalf of not holding stocks on day i: there are two possibilities to transfer to the current state: not holding stocks on the previous day, holding stocks on the previous day but selling them today
            dp[i][0] = Math.max(dp[i-1][0],dp[i-1][1]+prices[i]);
            // Represents holding stocks on day i: there are two possibilities to transfer to the current state: holding stocks on the previous day, not holding stocks on the previous day, but buying today. Multiple purchases are not supported. If you buy, you can only buy for the first time
            dp[i][1] =  Math.max(dp[i-1][1],-prices[i]);
        }
        // The best interest can only be sold
        return dp[prices.length-1][0];
    }
}

leetcode - 122. The best time to buy and sell stocks II

Give an array prices, where prices[i] is the price of a given stock on day I.
Design an algorithm to calculate the maximum profit you can make. You can complete as many transactions as possible (buying and selling a stock multiple times).
Note: you cannot participate in multiple transactions at the same time (you must sell the previous shares before buying again).

Example 1:
input: prices = [7,1,5,3,6,4]
output: 7
 explain: On day 2 (stock price) = 1)When buying, on day 3 (stock price) = 5)Sell at, The exchange is profitable = 5-1 = 4 . 
     Then, on day 4 (stock price) = 3)When buying, on day 5 (stock price) = 6)Sell at, The exchange is profitable = 6-3 = 3 . 
     
Example 2:
input: prices = [1,2,3,4,5]
output: 4
 explain: On day 1 (stock price) = 1)When buying, on day 5 (stock price) = 5)Sell at, The exchange is profitable = 5-1 = 4 . 
     Note that you can't buy stocks on day 1 and day 2 and then sell them. Because this belongs to multiple transactions at the same time, you must sell the previous stocks before buying again.
     
Example 3:
input: prices = [7,6,4,3,1]
output: 0
 explain: under these circumstances, No transaction completed, So the maximum profit is 0.

Solution: dynamic programming

class Solution {
    public int maxProfit(int[] prices) {
        // dp[i][j] represents the maximum profit that can be obtained: I represents day I, j=0 represents no shares held on day I, and j=1 represents shares held on day I
        if(prices==null || prices.length==0){
            return 0;
        }
        int[][] dp = new int[prices.length][2];
        // Do not hold shares on the first day
        dp[0][0] = 0;
        // First day holding shares
        dp[0][1] = -prices[0];
        for(int i=1;i<prices.length;i++){
            // Don't hold stocks on day i: don't hold stocks on day i-1. Hold stocks on day i-1 and sell them today
            dp[i][0] = Math.max(dp[i-1][0],dp[i-1][1]+prices[i]);
            // Holding stocks on day i: holding stocks on day i-1 and not on day i-1. i bought today and support multiple purchases
            dp[i][1] = Math.max(dp[i-1][1],dp[i-1][0]-prices[i]);
        }
        return dp[prices.length-1][0];
    }
}

leetcode - 123. The best time to buy and sell stocks III

Given an array, its ith element is the price of a given stock on day i.
Design an algorithm to calculate the maximum profit you can make. You can complete up to two transactions.
Note: you cannot participate in multiple transactions at the same time (you must sell the previous shares before buying again).

Example 1:
Input: prices = [3,3,5,0,0,3,1,4]
Output: 6
 Explanation: on day 4 (stock price) = 0)When buying, on day 6 (stock price) = 3)When sold, the exchange can make a profit = 3-0 = 3 . 
     Then, on day 7 (stock price) = 1)When buying, on day 8 (stock price) = 4)When sold, the exchange can make a profit = 4-1 = 3 . 
     
Example 2:
Input: prices = [1,2,3,4,5]
Output: 4
 Explanation: on day 1 (stock price) = 1)When buying, on day 5 (stock price) = 5)Sell at, The exchange is profitable = 5-1 = 4 .    
     Note that you can't buy stocks on day 1 and day 2 and then sell them.   
     Because you are involved in multiple transactions at the same time, you must sell the previous shares before buying again.
     
Example 3:
Input: prices = [7,6,4,3,1] 
Output: 0 
Explanation: in this case, No transaction completed, So the maximum profit is 0.

Example 4:
Input: prices = [1]
Output: 0 

Solution: dynamic programming

class Solution {
    public int maxProfit(int[] prices) {
        // dp[i][j] stands for the maximum profit that can be obtained: I stands for day I
        // j=0 represents the first holding, j=1 represents the first non holding, j=2 represents the second holding, and j=3 represents the second non holding
        if(prices==null || prices.length==0){
            return 0;
        }
        int[][] dp = new int[prices.length][4];
        dp[0][0] = -prices[0];
        dp[0][1] = 0;
        dp[0][2] = -prices[0];
        dp[0][3] = 0;
        for(int i=1;i<prices.length;i++){
            // First holding on day i: holding on the previous day, not holding on the previous day, buying for the first time today
            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]);
            dp[i][2] =  Math.max(dp[i-1][2],dp[i-1][1]-prices[i]);
            dp[i][3] =  Math.max(dp[i-1][3],dp[i-1][2]+prices[i]);
        }
        return Math.max(dp[prices.length-1][0],dp[prices.length-1][3]);
    }
}

simplify:

class Solution {
    public int maxProfit(int[] prices) {
        // dp[i][j] stands for the maximum profit that can be obtained: I stands for day I
        // j=0 represents the first holding, j=1 represents the first non holding, j=2 represents the second holding, and j=3 represents the second non holding
        if(prices==null || prices.length==0){
            return 0;
        }
        int[] dp = new int[4];
        // The first day, the first holding
        dp[0] = -prices[0];
        // The first day, the first non shareholding
        dp[1] = 0;
        // The first day, the second non shareholding: buy sell buy
        dp[2] = -prices[0];
        // The first day, the second non shareholding: buy sell buy sell
        dp[3] = 0;
        for(int i=1;i<prices.length;i++){
            // First holding on day i: holding on the previous day, not holding on the previous day, buying for the first time today
            dp[0] =  Math.max(dp[0],-prices[i]);
            dp[1] =  Math.max(dp[1],dp[0]+prices[i]);
            dp[2] =  Math.max(dp[2],dp[1]-prices[i]);
            dp[3] =  Math.max(dp[3],dp[2]+prices[i]);
        }
        return Math.max(dp[0],dp[3]);
    }
}

leetcode - 112. Path sum

Give you the root node root of the binary tree and an integer targetSum representing the target sum. Judge whether there is a path from the root node to the leaf node in the tree. The sum of all node values on this path is equal to the target and targetSum.

A leaf node is a node that has no children.

Method 1: deep search, dfs

When a leaf node is mentioned, the correct way is to judge that the left and right subtrees of the node are empty at the same time. Starting from the root node, whenever a node is encountered, the node value is deducted from the target value until the leaf node judges whether the target value has been deducted.

class Solution {
    public boolean hasPathSum(TreeNode root, int targetSum) {
        if(root==null){
            return false;
        }
        // Determine whether the node is a leaf node
        if(root.left==null && root.right==null){
            return targetSum == root.val;
        }
        // The operator | will judge whether the left is true. If it is true, the right will not be judged. If it is not true, continue to judge the right
        return hasPathSum(root.left,targetSum-root.val) || hasPathSum(root.right,targetSum-root.val);
    }
}

Method 2: breadth search, problem-solving thinking is similar to the common ancestor of binary tree

class Solution {
    // BFS
    public boolean hasPathSum(TreeNode root, int targetSum) {
        // Record the path and from the root node to the current node to prevent double calculation.
        // In this way, we use two queues to store the nodes to be traversed and the path and from the root node to these nodes respectively.
        if (root==null) {
            return false;
        }
        // Use a queue to traverse the node, and then use a queue to record the path and path of the traversed node
        Queue<TreeNode> nodeQueue = new LinkedList<>();
        Queue<Integer> sumQueue = new LinkedList<>();
        nodeQueue.add(root);
        sumQueue.add(0);
        while (!nodeQueue.isEmpty()){
            int size = nodeQueue.size();
            for(int i=0;i<nodeQueue.size();i++){
                TreeNode node = nodeQueue.poll();
                Integer sum = sumQueue.poll();
                if (node.left == null && node.right == null && node.val + sum == targetSum) {
                    return true;
                }
                if(node.left!=null){
                    nodeQueue.add(node.left);
                    sumQueue.add(node.val+sum);
                }
                if(node.right!=null){
                    nodeQueue.add(node.right);
                    sumQueue.add(node.val+sum);
                }
            }
        }
        return false;
    }
}

leetcode - 309. The best time to buy and sell stocks includes the freezing period

Given an array of integers, the ith element represents the stock price on day i. ‚Äč

Design an algorithm to calculate the maximum profit. You can complete as many transactions as possible (buying and selling a stock multiple times) under the following constraints:
You cannot participate in multiple transactions at the same time (you must sell the previous shares before buying again).
After selling stocks, you can't buy stocks the next day (i.e. the freezing period is 1 day).

Example:
input: [1,2,3,0,2]
output: 3 
explain: The corresponding transaction status is: [purchase, sell out, Freezing period, purchase, sell out] 

class Solution {
    public int maxProfit(int[] prices) {
        // dp[i][j]: the maximum profit on day I, where I represents day I and j represents the status of shares on that day: holding, non holding and freezing
        // j=0 represents shareholding, j=1 represents non shareholding and non freezing; j=2 represents non shareholding, frozen
        if(prices==null || prices.length==0){
            return 0;
        }
        int[][] dp = new int[prices.length][3];
        // Buy stocks on the first day
        dp[0][0] = -prices[0];
        // No shares bought (not held) on the first day
        dp[0][1] = 0;
        // Buy and sell stocks on the first day
        dp[0][2] = 0;

        for(int i=1;i<prices.length;i++){
            dp[i][0] = Math.max(dp[i-1][0],dp[i-1][1]-prices[i]);
            dp[i][1] = Math.max(dp[i-1][1],dp[i-1][2]);
            dp[i][2] = dp[i-1][0]+prices[i];
        }
        return Math.max(dp[prices.length-1][1],dp[prices.length-1][2]);
    }
}

leetcode - 714. The best time to buy and sell stocks includes handling charges

Given an integer array prices, where the i-th element represents the stock price on the i-th day; The integer fee represents the handling fee for trading stocks.

You can complete transactions indefinitely, but you need to pay a handling fee for each transaction. If you have bought a stock, you can't continue to buy it until you sell it.

Returns the maximum profit.

Note: a transaction here refers to the whole process of buying, holding and selling stocks. You only need to pay a handling fee for each transaction.

Example 1:
Input: prices = [1, 3, 2, 8, 4, 9], fee = 2
 Output: 8
 Explanation: the maximum profit that can be achieved:  
Buy here prices[0] = 1
 Sell here prices[3] = 8
 Buy here prices[4] = 4
 Sell here prices[5] = 9
 Total profit: ((8 - 1) - 2) + ((9 - 4) - 2) = 8

Example 2:
Input: prices = [1,3,7,5,10,3], fee = 3
 Output: 6 

Solution: dynamic programming

class Solution {
    public int maxProfit(int[] prices, int fee) {
        if(prices==null || prices.length==0){
            return 0;
        }
        // dp[i][j]: the maximum income obtained on day I, j=0 means holding, j=1 means not holding
        // j=0: hold the stock the previous day, do not hold it the previous day, buy it today
        // j=1: did not hold the stock the previous day, held it the previous day and sold it today (the handling fee is included when selling)
        int[][] dp = new int[prices.length][2];
        // First day holding shares
        dp[0][0] = -prices[0];
        // Do not hold shares on the first day
        dp[0][1] = 0;
        for(int i=1;i<prices.length;i++){
            dp[i][0] = Math.max(dp[i-1][0],dp[i-1][1]-prices[i]);
            dp[i][1] = Math.max(dp[i-1][1],dp[i-1][0]+prices[i]-fee);
        }
        return dp[prices.length-1][1];
    }
}

Method 2:

class Solution {
    public int maxProfit(int[] prices, int fee) {
        if(prices==null || prices.length==0){
            return 0;
        }
        // hold
        int host = -prices[0];
        // Not hold
        int nohost = 0;
        for(int i=1;i<prices.length;i++){
            host = Math.max(host,-prices[i]+nohost);
            nohost = Math.max(nohost,host+prices[i]-fee);
        }
        return Math.max(host,nohost);
    }
}

leetcode - 2. Add two numbers

Give you two non empty linked lists to represent two non negative integers. They store each number in reverse order, and each node can store only one number.

Please add the two numbers and return a linked list representing sum in the same form.

You can assume that neither number starts with 0 except the number 0.

Example 1:
Input: l1 = [2,4,3], l2 = [5,6,4]
Output:[7,0,8]
Explanation: 342 + 465 = 807.

Example 2:
Input: l1 = [0], l2 = [0]
Output:[0]

Example 3:
Input: l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
Output:[8,9,9,9,0,0,0,1]

Solution: double pointer

class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        // l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
        /**
         *        9  9  9  9  9  9  9
         *    +   9  9  9  9  0  0  0
         *   ------------------------------
         *        8  9  9  9  0  0  0  1
         */
        ListNode cur1 = l1;
        ListNode cur2 = l2;
        ListNode dummy = new ListNode(0);
        ListNode cur = dummy;
        int sum = 0;
        while (cur1!=null || cur2!=null){
            if(cur1!=null){
                sum = sum+cur1.val;
                cur1 = cur1.next;
            }
            if(cur2!=null){
                sum = sum+cur2.val;
                cur2 = cur2.next;
            }
            cur.next = new ListNode(sum%10);
            sum = sum/10;
            cur = cur.next;
        }
        if(sum==1){
            cur.next = new ListNode(1);
        }
        return dummy.next;
    }
}

leetcode - 415. String addition

Given two non negative integers num1 and num2 in string form, calculate their sum and return them in string form as well.

You cannot use any built-in library for handling large integers (such as BigInteger), nor can you directly convert the input string to integer form.

Example 1:
Input: num1 = "11", num2 = "123"
Output:"134"

Example 2:
Input: num1 = "456", num2 = "77"
Output:"533"

Example 3:
Input: num1 = "0", num2 = "0"
Output:"0"

Solution: double pointer

class Solution {
    public String addStrings(String num1, String num2) {
        /**
         *        9  9  9  9  9  9  9
         *    +   9  9  9  9  0  0  0
         *   ------------------------------
         *        8  9  9  9  0  0  0  1
         */
        int i = num1.length()-1;
        int j = num2.length()-1;
        // Sum of two numbers
        int sum = 0;
        StringBuilder stringBuilder = new StringBuilder();
        while (i>=0 || j>=0){
            if(i>=0){
                sum = sum + num1.charAt(i)-'0';
                i--;
            }
            if(j>=0){
                sum = sum + num2.charAt(j)-'0';
                j--;
            }
            stringBuilder.append(sum%10);
            sum = sum/10;
        }
        if(sum==1){
            stringBuilder.append(sum);
        }
        return stringBuilder.reverse().toString();
    }
}

Posted by ripcurlksm on Fri, 26 Nov 2021 12:07:01 -0800