# Catalogue of series articles

I Array type problem solving method 1: dichotomy

II Array type problem solving method 2: Double finger needle method

III Array type problem solving method 3: sliding window

IV Array type problem solving method 4: simulation

V The basic operation and classic topics of the linked list

Vi Classic title of hash table

VII Classic title of string

VIII KMP of string

IX Solution: double pointer

X Classic title of stack and queue

Xi top-K problem in stack and queue

XII The first, middle and last order traversal of binary tree

XIII Sequence traversal of binary tree and related topics

XIV Binary tree part of binary tree attributes related topics

XV Modification and construction of binary tree in binary tree chapter

XVI Properties of binary search tree

XVII The problem of common ancestor in binary tree discourse

XVIII Modification and construction of binary search tree in binary tree chapter

XIX Combinatorial problem of backtracking algorithm

XX Segmentation, subset and total arrangement of backtracking algorithm

Updating

# preface

The question brushing route comes from: Code Capriccio

Greedy algorithm: the local optimal solution is stacked into the global optimal solution. There is no fixed routine. It is common sense derivation and counter examples.

# Inscription

# 1, Simple topic

## 455. Distribution of biscuits

Leetcode link

Suppose you are a great parent and want to give your children some cookies. However, each child can only give one biscuit at most.

For each child I, there is an appetite value g[i], which is the minimum size of biscuits that can satisfy the children's appetite; And every cookie j has a size s[j]. If s[j] > = g[i], we can assign this biscuit j to child I, and the child will be satisfied. Your goal is to meet as many children as possible and output this maximum value.

Solution:

class Solution { public int findContentChildren(int[] g, int[] s) { // Sort first Arrays.sort(g); Arrays.sort(s); int i = 0; // Child subscript int j = 0; // Appetite subscript // And cookies and children while (i < g.length && j < s.length) { if (s[j] >= g[i]) { // Biscuits satisfy a child's appetite i++; j++; } else { // The child has too much appetite and looks back for big biscuits j++; } } return i; } }

## 1005. Maximum array sum after K negations

Leetcode link

Give you an integer array nums and an integer k. modify the array as follows:

Select a subscript i and replace num [i] with - num [i].

Repeat this process exactly k times. You can select the same subscript i multiple times. After modifying the array in this way, the maximum possible sum of the array is returned

Solution:

Invert the smallest number every time

class Solution { public int largestSumAfterKNegations(int[] nums, int k) { for (int i = 0; i < k; i++) { // Sort, reverse Arrays.sort(nums); nums[0] = -nums[0]; } // Sum int sum = 0; for (int i = 0; i < nums.length; i++) { sum += nums[i]; } return sum; } }

Optimization:

class Solution { public int largestSumAfterKNegations(int[] nums, int k) { // Sort first Arrays.sort(nums); // Invert the negative number in the [0,k) range for (int i = 0; i < nums.length; i++) { if (k > 0 && nums[i] < 0) { nums[i] = -nums[i]; k--; } } // See if the remaining k is even or odd if (k % 2 == 1) { // Odd number, invert the smallest number Arrays.sort(nums); nums[0] = -nums[0]; } // Even number without operation // Sum int sum = 0; for (int i = 0; i < nums.length; i++) { sum += nums[i]; } return sum; } }

## 860. Lemonade change

Leetcode link

At the lemonade stand, each glass of lemonade costs $5. Customers line up to buy your products, one cup at a time (in the order bill is paid).

Each customer buys only one glass of lemonade and then pays you $5, $10 or $20. You must give each customer the correct change, which means that the net transaction is $5 per customer. Note that you don't have any change at first. Give you an integer array bills, where bills[i] is the bill paid by the ith customer. If you can give each customer the correct change, return true, otherwise return false.

Solution:

Record the number of chapters of five yuan and ten yuan, and change the money according to the situation. When changing the money, the code is concise, and it is not necessary to judge whether there is money in hand. After finding the money, it is judged according to the positive and negative number of money.

class Solution { public boolean lemonadeChange(int[] bills) { int five = 0; int ten = 0; for (int i = 0; i < bills.length; i++) { // Case 1 Received 5 yuan if (bills[i] == 5) { five++; } // Case 2 Receive 10 yuan, change 5 quickly if (bills[i] == 10) { five--; ten++; } // Situation 3 Got 20, 10 fast, find the fast one first if (bills[i] == 20) { if (ten > 0) { ten--; five--; } else { five -= 3; } } // judge if (five < 0 || ten < 0) { return false; } } return true; } }

# 2, Medium topic

## 376. Swing sequence

Leetcode link

If the difference between consecutive numbers strictly alternates between positive and negative numbers, the number sequence is called swing sequence. The first difference (if any) may be positive or negative. A sequence with only one element or two unequal elements is also regarded as a swing sequence.

For example, [1, 7, 4, 9, 2, 5] is a swing sequence because the difference (6, - 3, 5, - 7, 3) is alternating positive and negative.

On the contrary, [1, 4, 7, 2, 5] and [1, 7, 4, 5, 5] are not swing sequences. The first sequence is because its first two differences are positive, and the second sequence is because its last difference is zero.

Subsequences can be obtained by deleting some (or no) elements from the original sequence, and the remaining elements maintain their original order.

Give you an integer array nums, which returns the length of the longest subsequence of the swing sequence in nums.

Solution:

Two consecutive pairs of differences are opposite, indicating swing

In special case, the longest swing subsequence of [2,2,5] is [2,5], but the difference is [0,5], so it is necessary to add equal to

class Solution { public int wiggleMaxLength(int[] nums) { if (nums.length <= 1) return nums.length; int preDiff = 0; // Last pair difference int curDiff = 0; // Current difference int count = 1; // record for (int i = 1; i < nums.length; i++) { curDiff = nums[i] - nums[i - 1]; // The difference between two consecutive pairs is opposite. Note that it is equal to if ((curDiff > 0 && preDiff <= 0) || (curDiff < 0 && preDiff >= 0)) { count++; preDiff = curDiff; } } return count; } }

## 738. Monotonically increasing numbers

Leetcode link

Solution:

Local optimization: when strNum[i - 1] > strNum[i], let strNum[i - 1] –, and then strNum[i] is 9

Traverse from the back to the front to find the position where you start to assign 9

class Solution { public int monotoneIncreasingDigits(int n) { if (n == 0) return 0; // Convert to char array char[] chars = String.valueOf(n).toCharArray(); int start = 10; // Maximum // Traverse from back to front for (int i = chars.length - 1; i > 0; i--) { if (chars[i] < chars[i - 1]) { chars[i - 1]--; start = i; } } // Splicing StringBuilder sb = new StringBuilder(); for (int i = 0; i < chars.length; i++) { // 10 - > 09, the first 0 is not spliced if (i == 0 && chars[i] == '0') continue; if (i >= start) { sb.append('9'); } else { sb.append(chars[i]); } } return Integer.valueOf(sb.toString()); } }

# 3, Stock buying problem

## 122. The best time to buy and sell stocks II

Leetcode link

Give an array prices, where prices[i] represents the price of the stock on day I. On each day, you may decide to buy and / or sell shares. You can only hold at most one share at any time. You can also buy it and sell it on the same day. Return the maximum profit you can make.

Solution:

Local optimization: collect the positive profit every day. As long as the stock price is greater than that of the previous day, it will be counted as profit

Global Optimization: obtain the maximum profit.

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

## 714. The best time to buy and sell stocks includes handling fees

Leetcode link

Give an integer array prices, where prices[i] represents the stock price on day I; 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.

Solution:

The purchase price plus handling fee is the purchase price of the previous day.

Different from the above question, we can't calculate the daily profit without brains. For example: [1, 4, 8], when fee = 2, buy it at the price of 1 + 2 = 3. It can't be sold the next day, and then sell it again on the third three days with only one handling charge. How to calculate it? It can be assumed that 3 yuan is bought on the first day and 4 yuan is sold on the second day. The selling price is recorded. Because the price on the third day is greater than 4, it is calculated according to (8 - 4) on the third day, and the handling fee is less

When is the real sale? When [1, 6, 3, 8], 6 - (1 + 2) + 8 - (3 + 2) > 8 - (1 + 2). Because 3 + 2 < 6, the buying price on the third day is 5 yuan, which is less than the selling price of the previous day by 6 yuan.

class Solution { public int maxProfit(int[] prices, int fee) { int sum = 0; // Initialize to the buying price of the first day int buy = prices[0] + fee; for (int i = 1; i < prices.length; i++) { if (prices[i] > buy) { // If you can make a profit, calculate the profit, and record the price of this false sale as the next purchase price sum += prices[i] - buy; buy = prices[i]; } else if (prices[i] + fee < buy) { // Real buying price buy = prices[i] + fee; } } return sum; } }

# 4, Two dimensional trade-off problem

## 135. Distribution of candy

Leetcode link

Solution:

Local optimization: if both sides consider together, they will consider one side at a time.

- Traverse from left to right. As long as the score on the right is greater than that on the left, the child on the right will have one more candy
- Traverse from right to left. As long as the score on the left is greater than that on the right, the child on the left will have one more candy
- Traverse again, and take the maximum value of the first two traversals for each position

class Solution { public int candy(int[] ratings) { int[] candyArr = new int[ratings.length]; candyArr[0] = 1; // The number of candy for the first child is 1 by default, starting from the second child for (int i = 1; i < ratings.length; i++) { candyArr[i] = ratings[i] > ratings[i - 1] ? candyArr[i - 1] + 1 : 1; } // The backward forward traversal starts from the penultimate child, and the last position is the result of more than one round of traversal for (int i = ratings.length - 2; i >= 0; i--) { int temp = ratings[i] > ratings[i + 1] ? candyArr[i + 1] + 1 : 1; candyArr[i] = Math.max(temp, candyArr[i]); } int res = 0; for (int i = 0; i < candyArr.length; i++) { res += candyArr[i]; } return res; } }

## 406. The cohort was reconstructed according to height

Leetcode link

Suppose a group of people who are out of order stand in a queue, and the array people represents the attributes of some people in the queue (not necessarily in order). Each person [i] = [Hi, Ki] means that the height of the ith person is hi, and there is just ki person whose height is greater than or equal to hi in front. Please reconstruct and return the queue represented by the input array people. The returned queue should be formatted as an array queue, where queue[j] = [hj, kj] is the attribute of the jth person in the queue (queue[0] is the person in front of the queue).

Solution:

Sort by height before inserting

class Solution { public int[][] reconstructQueue(int[][] people) { Arrays.sort(people, (p1, p2) -> { // Same, in ascending order of the second element if (p1[0] == p2[0]) return p1[1] - p2[1]; // Default descending order return p2[0] - p1[0]; }); List<int[]> List = new LinkedList<>(); for (int[] arr : people) { List.add(arr[1], arr); } return List.toArray(new int[people.length][]); } }