Gu Dequan: Personal homepage
Personal column: "Linux Operating System" "C/C++" "LeedCode Question Writing"
The keyboard is bad, and the annual salary is one million!
1. Minimum number of operations to reduce X to 0
Question link: Minimum number of operations to reduce x to 0
Question description
You are given an array of integers nums
and an integer x
. On each operation, you should remove nums
the leftmost or rightmost element of the array and then subtract that element's value x
from it . Note that the array needs to be modified for subsequent operations.
If it can be reduced x
to exactly0
, return the minimum operand ; otherwise, return -1
.
Example 1:
Input: nums = [1,1,4,2,3], x = 5 Output: 2 Explanation: The best solution is to remove the last two elements and reduce x to 0.
Example 2:
Input: nums = [5,6,7,8,9], x = 4 Output: -1
Example 3:
Input: nums = [3,2,20,1,1,3], x = 10 Output: 5 Explanation: The best solution is to remove the last three elements and the first two elements (5 operations in total), which will x decreases to 0
hint:
1 <= nums.length <= 105
1 <= nums[i] <= 104
1 <= x <= 109
solution
Algorithm idea:
The question requires the shortest array of two consecutive segments of the array "left end + right end" with a sum of - The longest array of x. At this point, it’s the familiar sliding window problem.
Algorithm flow:
a. Transformation problem: find target = sum(nums) - ×. If target < 0, the problem has no solution;
b. Initialize the left and right pointers l = 0, r = 0 (the sliding window interval is represented as [l, r). Whether the left and right intervals are open or closed is very important and must be set consistent with the code), and record the variable sum of the array sum in the current sliding window. = 0, record the maximum interval length of the array that currently satisfies the condition maxLen = -1;
c. When r is less than or equal to the length of the array, keep looping:
i. If sum < target, move the right pointer right until the variable sum is greater than or equal to target, or the right pointer has been moved to the head;
ii. If sum > target, move the left pointer right until the variable sum is less than or equal to target, or the left pointer has moved to the head;
ii. If sum == target is achieved after the first two steps of left and right movement, maintain the maximum length of the array that meets the conditions and allow the next element to enter the window;
d. After the loop ends, if the value of maxLen is meaningful, the calculation result is returned; otherwise, -1 is returned.
Code
class Solution
{
public:
int minOperations(vector<int>& nums, int x)
{
int sum = 0;
for(int a : nums) sum += a;
int target = sum - x;
if(target < 0)
return -1;
int ret = -1;
for(int left = 0, right = 0, tmp = 0; right < nums.size(); right++)
{
tmp += nums[right];
while(tmp > target)
tmp -= nums[left++];
if(tmp == target)
ret = max(ret, right - left + 1);
}
if(ret == -1)
return ret;
else return
nums.size() - ret;
}
};
2. Fruit baskets
Title link: Fruits in a basket
Question description
You are visiting a farm with a row of fruit trees planted from left to right. The trees are fruits
represented by an array of integers, where fruits[i]
is the type ofi
fruit on the first tree .
You want to collect as many fruits as possible. However, the owner of the farm has set some strict rules that you must follow to pick the fruits:
- You only have two baskets, and each basket can only hold a single type of fruit. There is no limit to the total amount of fruit that can be placed in each basket.
- You can choose any tree to start picking, and you must pick exactly one fruit from each tree (including the tree you started picking from) . Fruit picked should match the type of fruit in the basket. Each time you pick, you will move to the right to the next tree and continue picking.
- Once you get to a tree and the fruit doesn't match the fruit type for the basket, you have to stop picking.
Given an array of integers , return the maximumfruits
number of fruits you can collect .
Example 1:
Input: fruits = [ 1,2,1 ] Output: 3 Explanation: All 3 trees can be picked.
Example 2:
Input: fruits = [0, 1,2,2 ] Output: 3 Explanation: The three trees [1,2,2] can be picked. If you start picking from the first tree, you can only pick the two trees [0,1].
Example 3:
Input: fruits = [1, 2,3,2,2 ] Output: 4 Explanation: The four trees [2,3,2,2] can be picked. If you start picking from the first tree, you can only pick the two trees [1,2].
Example 4:
Input: fruits = [3,3,3, 1,2,1,1,2,3,3,4 ] Output: 5 Explanation: These five trees [1,2,1,1,2] can be picked.
hint:
1 <= fruits.length <= 105
0 <= fruits[i] < fruits.length
solution
Algorithm idea:
The object of study is a continuous interval, and the "sliding window" idea can be used to solve the problem. Let the sliding window satisfy: there are only two types of fruits in the window.
Method:
When the fruit at the right end enters the window, use the hash table to count the frequency of this fruit. After this fruit comes in, determine the size of the hash table; if the size exceeds 2: it means that there are more than two types of fruits in the window. Then draw the fruits out of the window starting from the left until the size of the hash table is less than or equal to 2, and then update the result; if it does not exceed 2, it means that there are no more than two types of fruits in the current window, and directly update the result ret.
Algorithm flow:
a. Initialize the hash table hash to count the type and quantity of fruits in the window;
b. Initialize variables: left and right pointers left =0, right =0, variable recording the result ret = 0; c. When right is smaller than the array size, the following loop is executed:
i. Put the current fruit into the hash table;
ii. Determine the size of the hash table after the current fruit comes in:
If it exceeds 2; slide the left element out of the window and reduce the frequency of the element in the hash table by one;
If the frequency of this element becomes 0 after being reduced by one, the element is deleted from the hash table;. Repeat the above two processes until the size in the hash table does not exceed 2;
iii.Update result ret;
iv. right++, let the next element enter the window; d. After the loop ends, ret stores the final result.
Code
class Solution
{
public:
int totalFruit(vector<int>& f)
{
unordered_map<int, int> hash;
int ret = 0;
for(int left = 0, right = 0; right < f.size(); right++)
{
hash[f[right]]++; // 进窗⼝
while(hash.size() > 2)
{
hash[f[left]]--;
if(hash[f[left]] == 0)
hash.erase(f[left]);
left++;
}
ret = max(ret, right - left + 1);
}
return ret;
}
3. Find all letter anagrams in the string
Question link: Find all letter anagrams in the string
Question description
Given two strings s
sum p
, find all substrings of allophones s
in and return the starting index of these substrings. The order of answer output is not taken into account.p
Allophones refer to strings formed by rearranging the same letters (including identical strings)
Example 1:
Input: s = "cbaebabacd", p = "abc" Output: [0,6] Explanation: The substring with starting index equal to 0 is "cba", which is an anagram of "abc". The substring with starting index equal to 6 is "bac", which is an anagram of "abc".
Example 2:
Input: s = "abab", p = "ab" Output: [0,1,2] Explanation: The substring with starting index equal to 0 is "ab", which is an anagram of "ab". The substring with starting index equal to 1 is "ba", which is an anagram of "ab". The substring with starting index equal to 2 is "ab", which is an anagram of "ab".
hint:
1 <= s.length, p.length <= 3 * 104
s
andp
contain only lowercase letters
solution
Algorithm idea:
Because the length of the anagrams of string p must be the same as the length of string p, we can construct a sliding window in string s with the same length as string p, and maintain each window in the sliding window. The number of each type of letters; when the number of each type of letters in the window is the same as the number of each type of letters in the string p, it means that the current window is an anagram of the string p;
Therefore, two arrays of size 26 can be used to simulate a hash table, one to save the number of occurrences of each character in the substring in s, and the other to save the number of occurrences of each character in p. In this way, you can determine whether two strings are anagrams.
Code
class Solution
{
public:
vector<int> findAnagrams(string s, string p)
{
vector<int> ret;
int hash1[26] = { 0 };
for(auto ch : p) hash1[ch - 'a']++;
int hash2[26] = { 0 };
int m = p.size();
for(int left = 0, right = 0, count = 0; right < s.size(); right++)
{
char in = s[right];
if(++hash2[in - 'a'] <= hash1[in - 'a'])
count++;
if(right - left + 1 > m)
{
char out = s[left++];
if(hash2[out - 'a']-- <= hash1[out - 'a'])
count--;
}
if(count == m)
ret.push_back(left);
}
return ret;
}
};
Conclusion: Today’s question sharing ends here. I hope that sharing this article will bring some help to everyone’s study. If you have any questions, you are welcome to leave a message in the comment area~~~