2055. Plates Between Candles
There is a long table with a line of plates and candles arranged on top of it. You are given a 0-indexed string s consisting of characters '*' and '|' only, where a '*' represents a plate and a '|' represents a candle.
You are also given a 0-indexed 2D integer array queries where queries[i] = [lefti, righti] denotes the substring s[lefti...righti] (inclusive). For each query, you need to find the number of plates between candles that are in the substring. A plate is considered between candles if there is at least one candle to its left and at least one candle to its right in the substring.
- For example,
s = "||**||**|*", and a query[3, 8]denotes the substring"*|| ** |". The number of plates between candles in this substring is2, as each of the two plates has at least one candle in the substring to its left and right.
Return an integer array answer where answer[i] is the answer to the ith query.
Example 1:
Input: s = "**|**|***|", queries = [[2,5],[5,9]]
Output: [2,3]
Explanation:
- queries[0] has two plates between candles.
- queries[1] has three plates between candles.
Example 2:
Input: s = "***|**|*****|**||**|*", queries = [[1,17],[4,5],[14,17],[5,11],[15,16]]
Output: [9,0,0,0,0]
Explanation:
- queries[0] has nine plates between candles.
- The other queries have zero plates between candles.
这道题可以通过预处理 + 前缀和的方法做出来,
第一次做的时候
是用一个array记录的所有蜡烛的位置,然后通过二分法去判断最左边和最右边的蜡烛
但是看答案之后有更合适的解法,除了前缀和的数组,再增加一个left和right的数组分别记录当前位置最左边和最右边的蜡烛的位置,这让查找只需要O(1)的时间复杂度, 前面预处理的时间复杂度是O(n), 总体的时间复杂度是O(n + q)
class Solution {
public int[] platesBetweenCandles(String s, int[][] queries) {
int n = s.length();
int[] presum = new int[n];
int sum = 0;
for(int i = 0; i < s.length(); i++) {
if(s.charAt(i) == '*') {
sum++;
}
presum[i] = sum;
}
int[] left = new int[n];
int l = -1;
for(int i = 0; i < s.length(); i++) {
if(s.charAt(i) == '|') {
l = i;
}
left[i] = l;
}
int[] right = new int[n];
int r = -1;
for(int i = s.length() - 1; i >= 0; i--) {
if(s.charAt(i) == '|') {
r = i;
}
right[i] = r;
}
int[] res = new int[queries.length];
for(int i = 0; i < queries.length; i++) {
int[] query = queries[i];
int start = query[0];
int end = query[1];
int x = right[start];
int y = left[end];
if(x == -1 || y == -1 || x >= y) {
res[i] = 0;
} else {
res[i] = presum[y] - presum[x];
}
}
return res;
}
}
1492. The kth Factor of n
You are given two positive integers n and k. A factor of an integer n is defined as an integer i where n % i == 0.
Consider a list of all factors of n sorted in ascending order, return the kth factor in this list or return -1 if n has less than k factors.
Example 1:
Input: n = 12, k = 3
Output: 3
Explanation: Factors list is [1, 2, 3, 4, 6, 12], the 3rd factor is 3.
Example 2:
Input: n = 7, k = 2
Output: 7
Explanation: Factors list is [1, 7], the 2nd factor is 7.
Example 3:
Input: n = 4, k = 4
Output: -1
Explanation: Factors list is [1, 2, 4], there is only 3 factors. We should return -1.
第一种方法就是直接遍历从1-n
因为给的constraint太小,只限制到1000,所以枚举是一个可行的方法
但是其实是可以只遍历到sqrt(n)的 然后再反过来遍历 sqrt(n) 到 1,但是要返回n/i(i是遍历的值)
特殊注意如果n是完全平方数,需要i--
class Solution {
public int kthFactor(int n, int k) {
int i = 1;
for(; i * i <= n; i++) {
if(n%i == 0) {
k--;
}
if(k == 0) {
return i;
}
}
i--;
if(i * i == n) {
i--;
}
for(; i > 0; i--) {
if(n%i == 0) {
k--;
}
if(k == 0) {
return n/i;
}
}
return -1;
}
}
1207. Unique Number of Occurrences
Given an array of integers arr, return true if the number of occurrences of each value in the array is unique or false otherwise.
Example 1:
Input: arr = [1,2,2,1,1,3]
Output: true
Explanation: The value 1 has 3 occurrences, 2 has 2 and 3 has 1. No two values have the same number of occurrences.
Example 2:
Input: arr = [1,2]
Output: false
Example 3:
Input: arr = [-3,0,1,-3,1,1,1,-3,10,0]
Output: true
这道题蛮简单的,值得注意的是,最后的结果可以通过直接比较map和set的大小得出
class Solution {
public boolean uniqueOccurrences(int[] arr) {
Map<Integer, Integer> map = new HashMap<>();
for(int num: arr) {
map.put(num, map.getOrDefault(num, 0) + 1);
}
Set<Integer> set = new HashSet<>();
for(int val: map.values()) {
set.add(val);
}
return map.size() == set.size();
}
}
2385. Amount of Time for Binary Tree to Be Infected
You are given the root of a binary tree with unique values, and an integer start. At minute 0, an infection starts from the node with value start.
Each minute, a node becomes infected if:
- The node is currently uninfected.
- The node is adjacent to an infected node.
Return the number of minutes needed for the entire tree to be infected.
Example 1:
Input: root = [1,5,3,null,4,10,6,9,2], start = 3
Output: 4
Explanation: The following nodes are infected during:
- Minute 0: Node 3
- Minute 1: Nodes 1, 10 and 6
- Minute 2: Node 5
- Minute 3: Node 4
- Minute 4: Nodes 9 and 2
It takes 4 minutes for the whole tree to be infected so we return 4.
Example 2:
Input: root = [1], start = 1
Output: 0
Explanation: At minute 0, the only node in the tree is infected so we return 0.
没做出来,想法没问题,但是在算从根节点到当前节点的层数的时候没想明白。应该就是初始从0开始 然后level就是层数了。
depth是从根节点到infected node的层数,所以depth - level就可以得到结果了。
对于起始结点,若该结点是一棵树的根结点,那么该结点感染整棵树所需时间为树的高度。如图中的3->10,6。
若起始节点存在父结点,则该结点还可以沿着父结点去感染父结点其其他子树。如图中的3->1->5->4->9,2。假设该起始结点在某结点的左子树上,那么它感染整棵树的时间为从起始节点到树的根结点的距离 + 根结点另一颗子树的高度。即根结点与起始节点的高度差 + 根结点另一颗子树的高度。
以上两种情况是同时进行的,所以最短时间为两者的最大值。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
int depth = -1;
int res = 0;
public int traversal(TreeNode root, int level, int start) {
if(root == null) return 0;
if(root.val == start) {
depth = level;
}
int l = traversal(root.left, level + 1, start);
boolean inLeft = depth != -1;
int r = traversal(root.right, level + 1, start);
if(root.val == start) {
res = Math.max(res, Math.max(l, r));
} else if(inLeft) {
res = Math.max(res, depth - level + r);
} else {
res = Math.max(res, depth - level + l);
}
return Math.max(l, r) + 1;
}
public int amountOfTime(TreeNode root, int start) {
traversal(root, 0, start);
return res;
}
}
2090. K Radius Subarray Averages
You are given a 0-indexed array nums of n integers, and an integer k.
The k-radius average for a subarray of nums centered at some index i with the radius k is the average of all elements in nums between the indices i - k and i + k (inclusive). If there are less than k elements before or after the index i, then the k-radius average is -1.
Build and return an array avgs of length n where avgs[i] is the k-radius average for the subarray centered at index i.
The average of x elements is the sum of the x elements divided by x, using integer division. The integer division truncates toward zero, which means losing its fractional part.
- For example, the average of four elements
2,3,1, and5is(2 + 3 + 1 + 5) / 4 = 11 / 4 = 2.75, which truncates to2.
Example 1:
Input: nums = [7,4,3,9,1,8,5,2,6], k = 3
Output: [-1,-1,-1,5,4,4,-1,-1,-1]
Explanation:
- avg[0], avg[1], and avg[2] are -1 because there are less than k elements before each index.
- The sum of the subarray centered at index 3 with radius 3 is: 7 + 4 + 3 + 9 + 1 + 8 + 5 = 37.
Using integer division, avg[3] = 37 / 7 = 5.
- For the subarray centered at index 4, avg[4] = (4 + 3 + 9 + 1 + 8 + 5 + 2) / 7 = 4.
- For the subarray centered at index 5, avg[5] = (3 + 9 + 1 + 8 + 5 + 2 + 6) / 7 = 4.
- avg[6], avg[7], and avg[8] are -1 because there are less than k elements after each index.
Example 2:
Input: nums = [100000], k = 0
Output: [100000]
Explanation:
- The sum of the subarray centered at index 0 with radius 0 is: 100000.
avg[0] = 100000 / 1 = 100000.
Example 3:
Input: nums = [8], k = 100000
Output: [-1]
Explanation:
- avg[0] is -1 because there are less than k elements before and after index 0.
两种做法:presum 或者 sliding window
然后别忘了数字相加过大可能溢出, 可以用long类型
class Solution {
public int[] getAverages(int[] nums, int k) {
int n = nums.length;
int[] res = new int[n];
Arrays.fill(res, -1);
long sum = 0;
if(2*k+1 > n) {
return res;
}
for(int i = 0; i < 2*k+1; i++) {
sum += nums[i];
}
res[k] = (int) Math.floor(sum/(2*k+1));
for(int i = k + 1; i < n-k; i++) {
sum += nums[i + k] - nums[i - k - 1];
res[i] = (int) Math.floor(sum/(2*k+1));
}
return res;
}
}
1838. Frequency of the Most Frequent Element
The frequency of an element is the number of times it occurs in an array.
You are given an integer array nums and an integer k. In one operation, you can choose an index of nums and increment the element at that index by 1.
Return the maximum possible frequency of an element after performing at most k operations.
Example 1:
Input: nums = [1,2,4], k = 5
Output: 3 Explanation: Increment the first element three times and the second element two times to make nums = [4,4,4].
4 has a frequency of 3.
Example 2:
Input: nums = [1,4,8,13], k = 5
Output: 2
Explanation: There are multiple optimal solutions:
- Increment the first element three times to make nums = [4,4,8,13]. 4 has a frequency of 2.
- Increment the second element four times to make nums = [1,8,8,13]. 8 has a frequency of 2.
- Increment the third element five times to make nums = [1,4,13,13]. 13 has a frequency of 2.
Example 3:
Input: nums = [3,9,6], k = 2
Output: 1
划窗划窗!已经想出来又觉得做不出来放弃了,还是要多想多做,思维更灵活啊。时间复杂度是nlog(n)
class Solution {
public int maxFrequency(int[] nums, int k) {
int res = 1;
Arrays.sort(nums);
int l = 0;
int r = 1;
long sum = 0;
while(r < nums.length) {
sum += (long) (nums[r] - nums[r-1]) * (r - l); // 这一步没想到
while(sum > k) {
sum -= nums[r] - nums[l];
l++;
}
res = Math.max(res, r - l + 1);
r++;
}
return res;
}
}
863. All Nodes Distance K in Binary Tree
Given the root of a binary tree, the value of a target node target, and an integer k, return an array of the values of all nodes that have a distance k from the target node.
You can return the answer in any order.
Example 1:
Input: root = [3,5,1,6,2,0,8,null,null,7,4], target = 5, k = 2
Output: [7,4,1]
Explanation: The nodes that are a distance 2 from the target node (with value 5) have values 7, 4, and 1.
Example 2:
Input: root = [1], target = 1, k = 3
Output: []
解决方法:把树转成图之后做,先记录下每一个节点的父节点,然后用bfs
class Solution {
Map<TreeNode, TreeNode> map = new HashMap<>();
public void traversal(TreeNode root, TreeNode target) {
if(root == null) return;
if(root.left != null) {
map.put(root.left, root);
traversal(root.left, target);
}
if(root.right != null) {
map.put(root.right, root);
traversal(root.right, target);
}
}
public List<Integer> distanceK(TreeNode root, TreeNode target, int k) {
traversal(root, target);
List<Integer> res = new ArrayList<>();
Deque<TreeNode> queue = new ArrayDeque<>();
Map<TreeNode, Boolean> visited = new HashMap<>();
queue.offer(target);
while(!queue.isEmpty() && k >= 0) {
int size = queue.size();
for(int i = 0; i < size; i++) {
TreeNode node = queue.poll();
visited.put(node, true);
if(k == 0) {
res.add(node.val);
}
if(node.left != null && !visited.containsKey(node.left)) {
queue.offer(node.left);
}
if(node.right != null && !visited.containsKey(node.right)) {
queue.offer(node.right);
}
if(map.containsKey(node) && !visited.containsKey(map.get(node))) {
queue.offer(map.get(node));
}
}
k--;
}
return res;
}
}
2542. Maximum Subsequence Score
You are given two 0-indexed integer arrays nums1 and nums2 of equal length n and a positive integer k. You must choose a subsequence of indices from nums1 of length k.
For chosen indices i0, i1, ..., ik - 1, your score is defined as:
- The sum of the selected elements from
nums1multiplied with the minimum of the selected elements fromnums2. - It can defined simply as:
(nums1[i0] + nums1[i1] +...+ nums1[ik - 1]) * min(nums2[i0] , nums2[i1], ... ,nums2[ik - 1]).
Return the maximum possible score.
A subsequence of indices of an array is a set that can be derived from the set {0, 1, ..., n-1} by deleting some or no elements.
Example 1:
Input: nums1 = [1,3,3,2], nums2 = [2,1,3,4], k = 3
Output: 12
Explanation:
The four possible subsequence scores are:
- We choose the indices 0, 1, and 2 with score = (1+3+3) * min(2,1,3) = 7.
- We choose the indices 0, 1, and 3 with score = (1+3+2) * min(2,1,4) = 6.
- We choose the indices 0, 2, and 3 with score = (1+3+2) * min(2,3,4) = 12.
- We choose the indices 1, 2, and 3 with score = (3+3+2) * min(1,3,4) = 8.
Therefore, we return the max score, which is 12.
Example 2:
Input: nums1 = [4,2,3,1,1], nums2 = [7,5,10,9,6], k = 1
Output: 30
Explanation:
Choosing index 2 is optimal: nums1[2] * nums2[2] = 3 * 10 = 30 is the maximum possible score.
这道题主要考的是priorityQueue以及数组排序
请记住:有序是一个非常好的性质。
可以借鉴的一个点就是用了一个id数组 然后对这个数组进行排序
然后priorityQueue只保存k-1个值,这k-1个是对应nums1中最大的,之后再加上当前id的nums1的值 然后乘以最小的nums2 就得到了最终结果
class Solution {
public long maxScore(int[] nums1, int[] nums2, int k) {
long res = 0L;
int n = nums1.length;
// 数组 nums2 按降序排列后的下标。
Integer[] ids = new Integer[n];
for (int i = 0; i < n; ++i) ids[i] = i;
Arrays.sort(ids, (i, j) -> nums2[j] - nums2[i]);
// nums1 的前 k - 1 个值的和
PriorityQueue<Integer> minHeap = new PriorityQueue<>(); // 小根堆
long sum1 = 0L;
for (int i = 0; i < k - 1; ++i) {
int id = ids[i];
sum1 += nums1[id];
minHeap.offer(nums1[id]);
}
// 从第 k 个元素(下标 k - 1)开始计算
for (int i = k - 1; i < n; ++i) {
int id = ids[i];
int num1 = nums1[id];
// 1. 加上 num1,构成 k 个数
sum1 += num1;
minHeap.offer(num1);
// 2. 比较
res = Math.max(sum1 * nums2[id], res);
// 3. 删除 k 个数中最小的数
sum1 -= minHeap.poll();
}
return res;
}
}
Design an algorithm that collects daily price quotes for some stock and returns the span of that stock's price for the current day.
The span of the stock's price in one day is the maximum number of consecutive days (starting from that day and going backward) for which the stock price was less than or equal to the price of that day.
- For example, if the prices of the stock in the last four days is
[7,2,1,2]and the price of the stock today is2, then the span of today is4because starting from today, the price of the stock was less than or equal2for4consecutive days. - Also, if the prices of the stock in the last four days is
[7,34,1,2]and the price of the stock today is8, then the span of today is3because starting from today, the price of the stock was less than or equal8for3consecutive days.
Implement the StockSpanner class:
StockSpanner()Initializes the object of the class.int next(int price)Returns the span of the stock's price given that today's price isprice.
Example 1:
Input
["StockSpanner", "next", "next", "next", "next", "next", "next", "next"]
[[], [100], [80], [60], [70], [60], [75], [85]]
Output
[null, 1, 1, 1, 2, 1, 4, 6]
Explanation
StockSpanner stockSpanner = new StockSpanner();
stockSpanner.next(100); // return 1
stockSpanner.next(80); // return 1
stockSpanner.next(60); // return 1
stockSpanner.next(70); // return 2
stockSpanner.next(60); // return 1
stockSpanner.next(75); // return 4, because the last 4 prices (including today's price of 75) were less than or equal to today's price.
stockSpanner.next(85); // return 6
单调栈的经典应用,找相邻的第一个比当前值大的或小的数
想到了是单调栈,但是没有最终应用上,除了单调栈外 还需要一个index记录当前是第几个数值
class StockSpanner {
int idx;
Deque<int[]> stack;
public StockSpanner() {
stack = new ArrayDeque<>();
stack.push(new int[]{-1, Integer.MAX_VALUE});
idx = -1;
}
public int next(int price) {
idx++;
while(price >= stack.peek()[1]) {
stack.pop();
}
int res = idx - stack.peek()[0];
stack.push(new int[]{idx, price});
return res;
}
}
1039. Minimum Score Triangulation of Polygon
You have a convex n-sided polygon where each vertex has an integer value. You are given an integer array values where values[i] is the value of the ith vertex (i.e., clockwise order).
You will triangulate the polygon into n - 2 triangles. For each triangle, the value of that triangle is the product of the values of its vertices, and the total score of the triangulation is the sum of these values over all n - 2 triangles in the triangulation.
Return the smallest possible total score that you can achieve with some triangulation of the polygon.
Example 1:
Input: values = [1,2,3]
Output: 6
Explanation: The polygon is already triangulated, and the score of the only triangle is 6.
Example 2:
Input: values = [3,7,4,5]
Output: 144
Explanation: There are two triangulations, with possible scores: 3*7*5 + 4*5*7 = 245, or 3*4*5 + 3*4*7 = 144.
The minimum score is 144.
Example 3:
Input: values = [1,3,1,4,1,5]
Output: 13
Explanation: The minimum score triangulation has score 1*1*3 + 1*1*4 + 1*1*5 + 1*1*1 = 13.
需要用dp + 记忆化存储去求解
class Solution {
int[] values;
Map<Integer, Integer> memo = new HashMap<>();
int n;
public int minScoreTriangulation(int[] values) {
this.n = values.length;
this.values = values;
return dfs(0, n-1);
}
public int dfs(int i, int j) {
if(i + 1 == j) {
return 0;
}
if(i + 2 == j) {
return values[i] * values[i+1] * values[i+2];
}
int key = i * n + j;
if(!memo.containsKey(key)) {
int res = Integer.MAX_VALUE;
for(int k = i + 1; k < j; k++) {
res = Math.min(res, dfs(i, k) + dfs(k, j) + values[i] * values[k] * values[j]);
}
memo.put(key, res);
}
return memo.get(key);
}
}
442. Find All Duplicates in an Array
Given an integer array nums of length n where all the integers of nums are in the range [1, n] and each integer appears once or twice, return an array of all the integers that appears twice.
You must write an algorithm that runs in O(n) time and uses only constant extra space.
Example 1:
Input: nums = [4,3,2,7,8,2,3,1]
Output: [2,3]
Example 2:
Input: nums = [1,1,2]
Output: [1]
Example 3:
Input: nums = [1]
Output: []
Constraints:
n == nums.length1 <= n <= 1051 <= nums[i] <= n- Each element in
numsappears once or twice.
这道题没注意看constraints 就是nums[i]是小于n的
有两种方法,一种是将所有的值i都换到i-1的位置 (原地哈希)
第二种是给nums[i] 加上负号标记
class Solution {
public void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public List<Integer> findDuplicates(int[] nums) {
for(int i = 0; i < nums.length; i++) {
while (nums[i] != nums[nums[i] - 1]) {
swap(nums, i, nums[i] - 1);
} // 持续交换 直到两个值相等为止
}
List<Integer> res = new ArrayList<>();
for(int i = 0; i < nums.length; i++) {
if(nums[i] - 1 != i) {
res.add(nums[i]);
}
}
return res;
}
}
class Solution {
public List<Integer> findDuplicates(int[] nums) {
int n = nums.length;
List<Integer> res = new ArrayList<>();
for(int i = 0; i < n; i++) {
int x = Math.abs(nums[i]);
if(nums[x-1] > 0) {
nums[x-1] = -nums[x-1];
} else {
res.add(x);
}
}
return res;
}
}
In English, we have a concept called root, which can be followed by some other word to form another longer word - let's call this word successor. For example, when the root "an" is followed by the successor word "other", we can form a new word "another".
Given a dictionary consisting of many roots and a sentence consisting of words separated by spaces, replace all the successors in the sentence with the root forming it. If a successor can be replaced by more than one root, replace it with the root that has the shortest length.
Return the sentence after the replacement.
Example 1:
Input: dictionary = ["cat","bat","rat"], sentence = "the cattle was rattled by the battery"
Output: "the cat was rat by the bat"
Example 2:
Input: dictionary = ["a","b","c"], sentence = "aadsfasf absbs bbab cadsfafs"
Output: "a a b c"
Constraints:
1 <= dictionary.length <= 10001 <= dictionary[i].length <= 100dictionary[i]consists of only lower-case letters.1 <= sentence.length <= 106sentenceconsists of only lower-case letters and spaces.- The number of words in
sentenceis in the range[1, 1000] - The length of each word in
sentenceis in the range[1, 1000] - Every two consecutive words in
sentencewill be separated by exactly one space. sentencedoes not have leading or trailing spaces.
做了一道trie的题,感觉对trie的模版还是掌握的不透,需要多写几遍
class Trie{
Trie[] children;
int length;
public Trie() {
this.children = new Trie[26];
this.length = -1;
}
public void insert(String word) {
Trie node = this;
for(int i = 0; i < word.length(); i++) {
char c = word.charAt(i);
int index = c - 'a';
if(node.children[index] == null) {
node.children[index] = new Trie();
}
node = node.children[index];
}
node.length = word.length();
}
public String search(String word) {
Trie node = this;
for(int i = 0; i < word.length(); i++) {
char c = word.charAt(i);
int index = c - 'a';
if(node.length != -1) {
return word.substring(0, i);
} else if(node.children[index] == null) {
return "";
}
node = node.children[index];
}
return "";
}
}
class Solution {
public String replaceWords(List<String> dictionary, String sentence) {
Trie trie = new Trie();
for(String word: dictionary) {
trie.insert(word);
}
String[] inputArr = sentence.split(" ");
StringBuilder sb = new StringBuilder();
for(String input: inputArr) {
String output = trie.search(input);
if(output.length() == 0) {
sb.append(input + " ");
} else {
sb.append(output + " ");
}
}
return sb.toString().trim();
}
}
10. Regular Expression Matching
Given an input string s and a pattern p, implement regular expression matching with support for '.' and '*' where:
'.'Matches any single character.'*'Matches zero or more of the preceding element.
The matching should cover the entire input string (not partial).
Example 1:
Input: s = "aa", p = "a"
Output: false
Explanation: "a" does not match the entire string "aa".
Example 2:
Input: s = "aa", p = "a*"
Output: true
Explanation: '*' means zero or more of the preceding element, 'a'. Therefore, by repeating 'a' once, it becomes "aa".
Example 3:
Input: s = "ab", p = ".*"
Output: true
Explanation: ".*" means "zero or more (*) of any character (.)".
Constraints:
1 <= s.length <= 201 <= p.length <= 20scontains only lowercase English letters.pcontains only lowercase English letters,'.', and'*'.- It is guaranteed for each appearance of the character
'*', there will be a previous valid character to match.
这道题是用dp做的,但是修修改改了不少,需要看一下答案缕清思路
2340. Minimum Adjacent Swaps to Make a Valid Array
You are given a 0-indexed integer array nums.
Swaps of adjacent elements are able to be performed on nums.
A valid array meets the following conditions:
- The largest element (any of the largest elements if there are multiple) is at the rightmost position in the array.
- The smallest element (any of the smallest elements if there are multiple) is at the leftmost position in the array.
Return the minimum swaps required to make nums a valid array.
Example 1:
Input: nums = [3,4,5,5,3,1]
Output: 6
Explanation: Perform the following swaps:
- Swap 1: Swap the 3rd and 4th elements, nums is then [3,4,5,3,5,1].
- Swap 2: Swap the 4th and 5th elements, nums is then [3,4,5,3,1,5].
- Swap 3: Swap the 3rd and 4th elements, nums is then [3,4,5,1,3,5].
- Swap 4: Swap the 2nd and 3rd elements, nums is then [3,4,1,5,3,5].
- Swap 5: Swap the 1st and 2nd elements, nums is then [3,1,4,5,3,5].
- Swap 6: Swap the 0th and 1st elements, nums is then [1,3,4,5,3,5].
It can be shown that 6 swaps is the minimum swaps required to make a valid array.
Example 2:
Input: nums = [9]
Output: 0
Explanation: The array is already valid, so we return 0.
还是道vip题,反正就是两种情况 一种maxIndex > minIndex 直接两次移动相加即可,如果minIndex > maxIndex 就是在相加的基础上减一即可
1268. Search Suggestions System
You are given an array of strings products and a string searchWord.
Design a system that suggests at most three product names from products after each character of searchWord is typed. Suggested products should have common prefix with searchWord. If there are more than three products with a common prefix return the three lexicographically minimums products.
Return a list of lists of the suggested products after each character of searchWord is typed.
Example 1:
Input: products = ["mobile","mouse","moneypot","monitor","mousepad"], searchWord = "mouse"
Output: [["mobile","moneypot","monitor"],["mobile","moneypot","monitor"],["mouse","mousepad"],["mouse","mousepad"],["mouse","mousepad"]]
Explanation: products sorted lexicographically = ["mobile","moneypot","monitor","mouse","mousepad"].
After typing m and mo all products match and we show user ["mobile","moneypot","monitor"].
After typing mou, mous and mouse the system suggests ["mouse","mousepad"].
Example 2:
Input: products = ["havana"], searchWord = "havana"
Output: [["havana"],["havana"],["havana"],["havana"],["havana"],["havana"]]
Explanation: The only word "havana" will be always suggested while typing the search word.
最开始觉得应该是从建立一个trie,然后在最后输出结果的时候用backtracking输出, 但是这种方法时间复杂度较高。
但是有更简单的方法,想到了但是没实施,就是在每个树的节点上加一个priorityQueue,这个Queue里存的就是当前节点的最小的三个单词 因为size最大才是3,所以没有占用很多的内存空间
class Trie{
Trie[] children;
PriorityQueue<String> pq;
public Trie() {
children = new Trie[26];
pq = new PriorityQueue<>((String c1, String c2) -> c2.compareTo(c1));
}
public void insert(String word) {
Trie node = this;
for(int i = 0; i < word.length(); i++) {
char ch = word.charAt(i);
int index = ch - 'a';
if(node.children[index] == null){
node.children[index] = new Trie();
}
node = node.children[index];
if(node.pq.size() < 3) {
node.pq.add(word);
} else{
node.pq.add(word);
node.pq.poll();
}
}
}
public PriorityQueue<String> searchPrefix(String prefix) {
Trie node = this;
for(int i = 0; i < prefix.length(); i++) {
char ch = prefix.charAt(i);
int index = ch - 'a';
if(node.children[index] == null){
return null;
}
node = node.children[index];
}
return node.pq;
}
}
class Solution {
public List<List<String>> suggestedProducts(String[] products, String searchWord) {
Trie trie = new Trie();
for(String product: products) {
trie.insert(product);
}
List<List<String>> res = new ArrayList<>();
for(int i = 0; i < searchWord.length(); i++) {
String substr = searchWord.substring(0, i+1);
List<String> sublist = new ArrayList<>();
PriorityQueue<String> pq = trie.searchPrefix(substr);
if(pq == null) {
res.add(sublist);
} else {
while(!pq.isEmpty()) {
sublist.add(pq.poll());
}
Collections.reverse(sublist);
res.add(sublist);
}
}
return res;
}
}
199. Binary Tree Right Side View
Given the root of a binary tree, imagine yourself standing on the right side of it, return the values of the nodes you can see ordered from top to bottom.
Example 1:
Input: root = [1,2,3,null,5,null,4]
Output: [1,3,4]
Example 2:
Input: root = [1,null,3]
Output: [1,3]
Example 3:
Input: root = []
Output: []
二叉树获取右视图方法 dfs 先遍历右边,如果深度首次遇到,就把当前root.val加入到result里
class Solution {
List<Integer> res = new ArrayList<>();
public void dfs(TreeNode root, int depth) {
if(root == null) return;
if(depth == res.size()) {
res.add(root.val);
}
dfs(root.right, depth + 1);
dfs(root.left, depth + 1);
}
public List<Integer> rightSideView(TreeNode root) {
dfs(root, 0);
return res;
}
}
There are two types of soup: type A and type B. Initially, we have n ml of each type of soup. There are four kinds of operations:
- Serve
100ml of soup A and0ml of soup B, - Serve
75ml of soup A and25ml of soup B, - Serve
50ml of soup A and50ml of soup B, and - Serve
25ml of soup A and75ml of soup B.
When we serve some soup, we give it to someone, and we no longer have it. Each turn, we will choose from the four operations with an equal probability 0.25. If the remaining volume of soup is not enough to complete the operation, we will serve as much as possible. We stop once we no longer have some quantity of both types of soup.
Note that we do not have an operation where all 100 ml's of soup B are used first.
Return the probability that soup A will be empty first, plus half the probability that A and B become empty at the same time. Answers within 10-5 of the actual answer will be accepted.
Example 1:
Input: n = 50
Output: 0.62500
Explanation: If we choose the first two operations, A will become empty first.
For the third operation, A and B will become empty at the same time.
For the fourth operation, B will become empty first.
So the total probability of A becoming empty first plus half the probability that A and B become empty at the same time, is 0.25 * (1 + 1 + 0.5 + 0) = 0.625.
Example 2:
Input: n = 100
Output: 0.71875
这道题两种解法: dp 或者 dfs + 记忆化搜索 都可以解决,不过要注意题中说的
Answers within 10-5 of the actual answer will be accepted.
就是直接用可能会超时,但是超过一定数值,最后结果返回是1
540. Single Element in a Sorted Array
You are given a sorted array consisting of only integers where every element appears exactly twice, except for one element which appears exactly once.
Return the single element that appears only once.
Your solution must run in O(log n) time and O(1) space.
Example 1:
Input: nums = [1,1,2,3,3,4,4,8,8]
Output: 2
Example 2:
Input: nums = [3,3,7,7,10,11,11]
Output: 10
Constraints:
1 <= nums.length <= 1050 <= nums[i] <= 105
根据m的index的位置判断左边/右边是否有单个数 复杂写法:
class Solution {
public int singleNonDuplicate(int[] nums) {
int left = 0;
int right = nums.length;
while(left < right) {
int mid = left + (right - left) / 2;
if(mid > 0 && nums[mid] == nums[mid-1]) {
if(mid % 2 == 0) {
right = mid;
} else {
left = mid+1;
}
} else if (mid < nums.length - 1 && nums[mid] == nums[mid+1]) {
if(mid % 2 == 1) {
right = mid;
} else {
left = mid+1;
}
} else {
return nums[mid];
}
}
return -1;
}
}
You are given an n x n integer matrix board where the cells are labeled from 1 to n2 in a Boustrophedon style starting from the bottom left of the board (i.e. board[n - 1][0]) and alternating direction each row.
You start on square 1 of the board. In each move, starting from square curr, do the following:
-
Choose a destination square
nextwith a label in the range[curr + 1, min(curr + 6, n2)].- This choice simulates the result of a standard 6-sided die roll: i.e., there are always at most 6 destinations, regardless of the size of the board.
-
If
nexthas a snake or ladder, you must move to the destination of that snake or ladder. Otherwise, you move tonext. -
The game ends when you reach the square
n2.
A board square on row r and column c has a snake or ladder if board[r][c] != -1. The destination of that snake or ladder is board[r][c]. Squares 1 and n2 do not have a snake or ladder.
Note that you only take a snake or ladder at most once per move. If the destination to a snake or ladder is the start of another snake or ladder, you do not follow the subsequent snake or ladder.
- For example, suppose the board is
[[-1,4],[-1,3]], and on the first move, your destination square is2. You follow the ladder to square3, but do not follow the subsequent ladder to4.
Return the least number of moves required to reach the square n2 . If it is not possible to reach the square, return -1.
Example 1:
Input: board = [[-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1],[-1,35,-1,-1,13,-1],[-1,-1,-1,-1,-1,-1],[-1,15,-1,-1,-1,-1]]
Output: 4
Explanation:
In the beginning, you start at square 1 (at row 5, column 0).
You decide to move to square 2 and must take the ladder to square 15.
You then decide to move to square 17 and must take the snake to square 13.
You then decide to move to square 14 and must take the ladder to square 35.
You then decide to move to square 36, ending the game.
This is the lowest possible number of moves to reach the last square, so return 4.
Example 2:
Input: board = [[-1,-1],[-1,3]]
Output: 1
这道题是经典bfs,bfs + visited数组, 为什么要加visited数组呢?避免重复计算。 eg:比如通过17跳到13,和正常从1到13。先别加入到queue了之后就不用再加了
class Solution {
public int snakesAndLadders(int[][] board) {
int m = board.length;
int n = board[0].length;
Deque<Integer> queue = new ArrayDeque<>();
boolean[] visited = new boolean[m*n+2];
queue.offer(1);
visited[1] = true;
int res = 1;
boolean flag = false;
outerloop: while(!queue.isEmpty()) {
int size = queue.size();
for(int i = 0; i < size; i++) {
int x = queue.poll();
for(int j = x+1; j <= Math.min(x+6, m*n); j++) {
if(j == m*n) {
flag = true;
break outerloop;
}
int row = m - (j - 1)/n - 1;
int col = ((j-1)/n) % 2 == 0 ? (j-1)%n : n - 1 - (j-1)%n;
int num = board[row][col];
if(num == m*n) {
flag = true;
break outerloop;
} else if(num != -1) {
if(!visited[num]) {
queue.add(num);
visited[num] = true;
}
} else if(!visited[j]) {
queue.add(j);
visited[j] = true;
}
// System.out.println(queue);
}
}
res++;
}
return flag ? res : -1;
}
}
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"
Example 2:
Input: strs = ["dog","racecar","car"]
Output: ""
Explanation: There is no common prefix among the input strings.
横向检测/纵向检测 横向检测: 暴力解法 纵向检测: 也相当于暴力解法
A gene string can be represented by an 8-character long string, with choices from 'A', 'C', 'G', and 'T'.
Suppose we need to investigate a mutation from a gene string startGene to a gene string endGene where one mutation is defined as one single character changed in the gene string.
- For example,
"AACCGGTT" --> "AACCGGTA"is one mutation.
There is also a gene bank bank that records all the valid gene mutations. A gene must be in bank to make it a valid gene string.
Given the two gene strings startGene and endGene and the gene bank bank, return the minimum number of mutations needed to mutate from startGene to endGene. If there is no such a mutation, return -1.
Note that the starting point is assumed to be valid, so it might not be included in the bank.
Example 1:
Input: startGene = "AACCGGTT", endGene = "AACCGGTA", bank = ["AACCGGTA"]
Output: 1
Example 2:
Input: startGene = "AACCGGTT", endGene = "AAACGGTA", bank = ["AACCGGTA","AACCGCTA","AAACGGTA"]
Output: 2
一道bfs的题
class Solution {
char[] types = new char[]{'A', 'C', 'G', 'T'};
public int minMutation(String startGene, String endGene, String[] bank) {
Map<String, Integer> map = new HashMap<>();
Map<String, Integer> visited = new HashMap<>();
for(String gene: bank) {
map.put(gene, 0);
}
if(!map.containsKey(endGene)) {
return -1;
}
Deque<String> queue = new ArrayDeque<>();
queue.offer(startGene);
visited.put(startGene, 1);
int step = 0;
while(!queue.isEmpty()) {
int size = queue.size();
for(int k = 0; k < size; k++) {
String gene = queue.poll();
char[] geneArr = gene.toCharArray();
for(int i = 0; i < gene.length(); i++) {
char ch = gene.charAt(i);
for(char type: types) {
if(type != ch) {
geneArr[i] = type;
String next = new String(geneArr);
if(next.equals(endGene)) {
return step+1;
}
if(!visited.containsKey(next) && map.containsKey(next)) {
queue.offer(next);
visited.put(next, 1);
}
}
}
geneArr[i] = ch;
}
}
step++;
}
return -1;
}
}
1567. Maximum Length of Subarray With Positive Product
Given an array of integers nums, find the maximum length of a subarray where the product of all its elements is positive.
A subarray of an array is a consecutive sequence of zero or more values taken out of that array.
Return the maximum length of a subarray with positive product.
Example 1:
Input: nums = [1,-2,-3,4]
Output: 4
Explanation: The array nums already has a positive product of 24.
Example 2:
Input: nums = [0,1,-2,-3,-4]
Output: 3
Explanation: The longest subarray with positive product is [1,-2,-3] which has a product of 6.
Notice that we cannot include 0 in the subarray since that'll make the product 0 which is not positive.
Example 3:
Input: nums = [-1,-2,-3,0,1]
Output: 2
Explanation: The longest subarray with positive product is [-1,-2] or [-2,-3].
解法一:贪心解法 num == 0 正负数统计清零 定义两个变量 n 和 p,分别代表 乘积为负数的子串长度 和 乘积为正数的子串长度 每次非零数都统计最大正数统计长度
class Solution {
public int getMaxLen(int[] nums) {
int n = 0; // 乘积为负数的子串长度
int p = 0; // 乘积为正数的子串长度
int res = 0;
for(int num: nums) {
if(num == 0) {
n = 0;
p = 0;
} else if(num > 0) {
p++;
if(n > 0) {
n++;
}
res = Math.max(res, p);
} else {
int temp = n;
n = p;
p = temp;
n++;
if(p > 0) {
p++;
}
res = Math.max(res, p);
}
}
return res;
}
}
dp解法:
class Solution {
public int getMaxLen(int[] nums) {
int n = nums.length;
int[] positive = new int[n];
int[] negative = new int[n];
positive[0] = nums[0] > 0 ? 1 : 0;
negative[0] = nums[0] < 0 ? 1 : 0;
int res = positive[0];
for(int i = 1; i < n; i++) {
if(nums[i] == 0) {
positive[i] = 0;
negative[i] = 0;
} else if(nums[i] > 0) {
positive[i] = positive[i-1] + 1;
negative[i] = negative[i-1] > 0 ? negative[i-1] + 1 : 0;
} else {
positive[i] = negative[i-1] > 0 ? negative[i-1] + 1 : 0;
negative[i] = positive[i-1] + 1;
}
res = Math.max(res, positive[i]);
}
return res;
}
}
2357. Make Array Zero by Subtracting Equal Amounts
You are given a non-negative integer array nums. In one operation, you must:
- Choose a positive integer
xsuch thatxis less than or equal to the smallest non-zero element innums. - Subtract
xfrom every positive element innums.
Return the minimum number of operations to make every element in nums equal to 0.
Example 1:
Input: nums = [1,5,0,3,5]
Output: 3
Explanation:
In the first operation, choose x = 1. Now, nums = [0,4,0,2,4].
In the second operation, choose x = 2. Now, nums = [0,2,0,0,2].
In the third operation, choose x = 2. Now, nums = [0,0,0,0,0].
Example 2:
Input: nums = [0]
Output: 0
Explanation: Each element in nums is already 0 so no operations are needed.
可以直接用哈希法来做,判断有多少个不相等的正整数
class Solution {
public int minimumOperations(int[] nums) {
Set<Integer> set = new HashSet<>();
for(int n: nums) {
if(n > 0) {
set.add(n);
}
}
return set.size();
}
}