1002. Find Common Characters
Given a string array words, return an array of all characters that show up in all strings within the words (including duplicates) . You may return the answer in any order.
Example 1:
Input: words = ["bella","label","roller"]
Output: ["e","l","l"]
Example 2:
Input: words = ["cool","lock","cook"]
Output: ["c","o"]
看上去很简单,但是好几次没做出来。解法就是每个word都建立一个哈希,然后通过这些word的哈希比对最后拿到结果
class Solution {
public List<String> commonChars(String[] words) {
int[] hashString = new int[26];
String firstWord = words[0];
for(char ch: firstWord.toCharArray()) {
hashString[ch-'a']++;
}
for(int i = 1; i < words.length; i++) {
int[] hashOtherString = new int[26];
for(char ch: words[i].toCharArray()) {
hashOtherString[ch-'a']++;
}
for(int j = 0; j < 26; j++) {
hashString[j] = Math.min(hashString[j], hashOtherString[j]);
}
}
List<String> res = new ArrayList<>();
for(int i = 0; i < 26; i++) {
for(int j = 0; j < hashString[i]; j++) {
char curr = (char) ('a'+i);
res.add(curr+"");
}
}
return res;
}
}
2934. Minimum Operations to Maximize Last Elements in Arrays
You are given two 0-indexed integer arrays, nums1 and nums2, both having length n.
You are allowed to perform a series of operations (possibly none).
In an operation, you select an index i in the range [0, n - 1] and swap the values of nums1[i] and nums2[i].
Your task is to find the minimum number of operations required to satisfy the following conditions:
nums1[n - 1]is equal to the maximum value among all elements ofnums1, i.e.,nums1[n - 1] = max(nums1[0], nums1[1], ..., nums1[n - 1]).nums2[n - 1]is equal to the maximum value among all elements ofnums2, i.e.,nums2[n - 1] = max(nums2[0], nums2[1], ..., nums2[n - 1]).
Return an integer denoting the minimum number of operations needed to meet both conditions, or -1 if it is impossible to satisfy both conditions.
Example 1:
Input: nums1 = [1,2,7], nums2 = [4,5,3]
Output: 1
Explanation: In this example, an operation can be performed using index i = 2.
When nums1[2] and nums2[2] are swapped, nums1 becomes [1,2,3] and nums2 becomes [4,5,7].
Both conditions are now satisfied.
It can be shown that the minimum number of operations needed to be performed is 1.
So, the answer is 1.
Example 2:
Input: nums1 = [2,3,4,5,9], nums2 = [8,8,4,4,4]
Output: 2
Explanation: In this example, the following operations can be performed:
First operation using index i = 4.
When nums1[4] and nums2[4] are swapped, nums1 becomes [2,3,4,5,4], and nums2 becomes [8,8,4,4,9].
Another operation using index i = 3.
When nums1[3] and nums2[3] are swapped, nums1 becomes [2,3,4,4,4], and nums2 becomes [8,8,4,5,9].
Both conditions are now satisfied.
It can be shown that the minimum number of operations needed to be performed is 2.
So, the answer is 2.
Example 3:
Input: nums1 = [1,5,4], nums2 = [2,5,3]
Output: -1
Explanation: In this example, it is not possible to satisfy both conditions.
So, the answer is -1.
Constraints:
1 <= n == nums1.length == nums2.length <= 10001 <= nums1[i] <= 1091 <= nums2[i] <= 109
思路问题,解法并不难,其实就是用贪心分情况讨论
class Solution {
// 分情况讨论
public int minOperations(int[] nums1, int[] nums2) {
int n = nums1.length;
int last1 = nums1[n - 1];
boolean flag1 = false;
int swap1 = 0;
int last2 = nums2[n - 1];
boolean flag2 = false;
int swap2 = 0;
for(int i = 0; i < n - 1; i++) {
if(nums1[i] <= last1 && nums2[i] <= last2) {
continue;
} else if(nums1[i] <= last2 && nums2[i] <= last1) {
swap1++;
} else {
flag1 = true;
break;
}
}
for(int i = 0; i < n - 1; i++) {
if(nums1[i] <= last2 && nums2[i] <= last1) {
continue;
} else if(nums1[i] <= last1 && nums2[i] <= last2) {
swap2++;
} else {
flag2 = true;
break;
}
}
if(flag1 && flag2) {
return -1;
}
return Math.min(swap1, swap2+1);
}
}
2863. Maximum Length of Semi-Decreasing Subarrays
You are given an integer array nums.
Return the length of the longest semi-decreasing subarray of nums , and 0 if there are no such subarrays.
- A subarray is a contiguous non-empty sequence of elements within an array.
- A non-empty array is semi-decreasing if its first element is strictly greater than its last element.
Example 1:
Input: nums = [7,6,5,4,3,2,1,6,10,11]
Output: 8
Explanation: Take the subarray [7,6,5,4,3,2,1,6].
The first element is 7 and the last one is 6 so the condition is met.
Hence, the answer would be the length of the subarray or 8.
It can be shown that there aren't any subarrays with the given condition with a length greater than 8.
Example 2:
Input: nums = [57,55,50,60,61,58,63,59,64,60,63]
Output: 6
Explanation: Take the subarray [61,58,63,59,64,60].
The first element is 61 and the last one is 60 so the condition is met.
Hence, the answer would be the length of the subarray or 6.
It can be shown that there aren't any subarrays with the given condition with a length greater than 6.
Example 3:
Input: nums = [1,2,3,4]
Output: 0
Explanation: Since there are no semi-decreasing subarrays in the given array, the answer is 0.
Constraints:
1 <= nums.length <= 105-109 <= nums[i] <= 109
用栈做 因为(i,j)左边肯定不会出现比i大的 右边肯定不会出现比j小的 所以建立一个单调栈,然后从下到上是单调递增的
之后从最后开始遍历,如果stack.peek()对应的值大于当前的值,就抛出 然后下一个知道遍历结束
class Solution {
public int maxSubarrayLength(int[] nums) {
Stack<Integer> stack = new Stack<>();
for(int i = 0; i < nums.length; i++) {
if(stack.isEmpty() || nums[stack.peek()] < nums[i]) {
stack.push(i);
}
}
int ans = 0;
for(int j = nums.length - 1; j >= 0; j--) {
while(!stack.isEmpty() && nums[stack.peek()] > nums[j]) {
int i = stack.pop();
ans = Math.max(ans, (j - i + 1));
}
}
return ans;
}
}
You are given a series of video clips from a sporting event that lasted time seconds. These video clips can be overlapping with each other and have varying lengths.
Each video clip is described by an array clips where clips[i] = [starti, endi] indicates that the ith clip started at starti and ended at endi.
We can cut these clips into segments freely.
- For example, a clip
[0, 7]can be cut into segments[0, 1] + [1, 3] + [3, 7].
Return the minimum number of clips needed so that we can cut the clips into segments that cover the entire sporting event [0, time]. If the task is impossible, return -1.
Example 1:
Input: clips = [[0,2],[4,6],[8,10],[1,9],[1,5],[5,9]], time = 10
Output: 3
Explanation: We take the clips [0,2], [8,10], [1,9]; a total of 3 clips.
Then, we can reconstruct the sporting event as follows:
We cut [1,9] into segments [1,2] + [2,8] + [8,9].
Now we have segments [0,2] + [2,8] + [8,10] which cover the sporting event [0, 10].
Example 2:
Input: clips = [[0,1],[1,2]], time = 5
Output: -1
Explanation: We cannot cover [0,5] with only [0,1] and [1,2].
Example 3:
Input: clips = [[0,1],[6,8],[0,2],[5,6],[0,4],[0,3],[6,7],[1,3],[4,7],[1,4],[2,5],[2,6],[3,4],[4,5],[5,7],[6,9]], time = 9
Output: 3
Explanation: We can take clips [0,4], [4,7], and [6,9].
dp 和 贪心结果要补上
1530. Number of Good Leaf Nodes Pairs
You are given the root of a binary tree and an integer distance. A pair of two different leaf nodes of a binary tree is said to be good if the length of the shortest path between them is less than or equal to distance.
Return the number of good leaf node pairs in the tree.
Example 1:
Input: root = [1,2,3,null,4], distance = 3
Output: 1
Explanation: The leaf nodes of the tree are 3 and 4 and the length of the shortest path between them is 3. This is the only good pair.
Example 2:
Input: root = [1,2,3,4,5,6,7], distance = 3
Output: 2
Explanation: The good pairs are [4,5] and [6,7] with shortest path = 2. The pair [4,6] is not good because the length of ther shortest path between them is 4.
Example 3:
Input: root = [7,1,4,6,null,5,3,null,null,null,null,null,2], distance = 3
Output: 1
Explanation: The only good pair is [2,5].
怎么递归比较重要,create一个pair 1)与 root 之间的不同的距离有多少叶子节点 2) 以 root 为根节点的子树中好叶子节点对的数量
class Pair {
int[] depth;
int count;
Pair(int[] depth, int count) {
this.depth = depth;
this.count = count;
}
}
class Solution {
public int countPairs(TreeNode root, int distance) {
Pair pair = dfs(root, distance);
return pair.count;
}
// the count of every distance, count less than distance
public Pair dfs(TreeNode root, int distance) {
int[] depth = new int[distance+1];
if(root.left == null && root.right == null) {
depth[0] = 1;
return new Pair(depth, 0);
}
int[] leftDepth = new int[distance+1];
int[] rightDepth = new int[distance+1];
int leftcount = 0;
int rightcount = 0;
int count = 0;
if(root.left != null) {
Pair left = dfs(root.left, distance);
leftDepth = left.depth;
leftcount = left.count;
}
if(root.right != null) {
Pair right = dfs(root.right, distance);
rightDepth = right.depth;
rightcount = right.count;
}
for(int i = 0; i < distance; i++) {
depth[i+1] += leftDepth[i];
depth[i+1] += rightDepth[i];
}
for(int i = 0; i <= distance; i++) {
for(int j = 0; i + j + 2 <= distance; j++) {
count += leftDepth[i] * rightDepth[j];
}
}
return new Pair(depth, count + leftcount + rightcount);
}
}
总结:
- backtracking的时候,stringbuilder是需要back的 todo:
- 886 并查集
- 1861 用queue做
- 694 可以用string来hash
- 1366 重新做一遍 自定义排序
- 1275 可以用填充法做一遍 官解这写的也太,,,,简单维护数组写值,按位置轮流填充1和-1,然后分别检查每行每列以及对角线的值之和的绝对值是否为3即可,再根据每次判断的公共元素的符号返回A或者B
class Solution {
public:
string tictactoe(vector<vector<int>>& moves) {
int tmp[3][3]{};
for (int i = 1; auto & v : moves) {
tmp[v[0]][v[1]] = i;
i = -i;
}
if (abs(tmp[0][0] + tmp[1][1] + tmp[2][2]) == 3 || abs(tmp[0][2] + tmp[1][1] + tmp[2][0]) == 3)
return tmp[1][1] > 0 ? "A" : "B";
for (int i = 0; i < 3; ++i)
if (abs(tmp[i][0] + tmp[i][1] + tmp[i][2]) == 3 || abs(tmp[0][i] + tmp[1][i] + tmp[2][i]) == 3)
return tmp[i][i] > 0 ? "A" : "B";
return moves.size() == 9 ? "Draw" : "Pending";
}
};
- 670 Maximum Swap 贪心法
class Solution {
public void swap(char[] arr, int i, int j) {
char temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public int maximumSwap(int num) {
String str = String.valueOf(num);
int n = str.length();
int max = -1;
int[] pair = {-1, -1};
int maxIndex = -1;
for(int i = n-1; i >= 0; i--) {
int curr = Integer.valueOf(str.charAt(i));
if(curr > max) {
max = curr;
maxIndex = i;
} else if(curr < max) {
pair[0] = i;
pair[1] = maxIndex;
}
}
if(pair[1] == -1 || pair[0] == -1) {
return num;
}
char[] arr = str.toCharArray();
swap(arr, pair[0], pair[1]);
return Integer.valueOf(new String(arr));
}
}
- 1029 可以选出
price_A - price_B最小的 N 个人,让他们飞往A市,其余人飞往B市。