717. 1-bit and 2-bit characters [simple question] [daily question]
Idea:
- Traverse the bits array from front to back. If the current element is 1, the second character, whether 10 or 11, starts with 1, so you can be sure that the current element and its next element form the second character, i+= 2 directly; The bits array has only 0 and 1. If it is not 1, it must be 0, and only the first character starts with 0 and occupies only one bit. Therefore, if the current element is the last bit, the last bit can constitute the first character, so it directly returns true. If it is not the last bit, i + +.
- If you can jump out of the for loop, it means that the last bit cannot form a character at this time, so false is returned.
code:
class Solution { public boolean isOneBitCharacter(int[] bits) { int len = bits.length,i = 0; while (i<len){ if (bits[i] == 1){ i+=2; }else { if (i == len-1){ return true; }else { i++; } } } return false; } }
Time:
18. Sum of four numbers [medium question]
Idea:
- Similar to the sum of three numbers, the sum of four numbers in this question first fixes the first number, then fixes the second number, and then the double pointer represents the last two numbers. The implementation idea is to sort first, and the array becomes larger from left to right. Therefore, after the current two numbers are fixed, if the sum of the last two numbers and the first two numbers is greater than the target, the right pointer moves to the left, and if it is less than the target, Move the left pointer to the right. If it is equal to target, it means that these four numbers are the four numbers we are looking for. Add them to the ANS list. At the same time, the topic requires that the four tuples cannot be the same, so you can use hashset to de duplicate them. The method is to define ans as hashset format and then return new
ArrayList(ans). - The focus of this question is not on the idea of solving the problem, but on how to prune. It was written according to the above idea. It took 116ms and beat 5%. As soon as I saw that the time was wrong, it was too long. I went to see the solution and found that it was the same idea, but it was pruned. I thought, I'll try to prune it, too. I haven't seen the solution code at this time.
- For the first modification, after adding the first fixed number, if the first four numbers are greater than the target, directly exit the for loop of the first layer; If the first four numbers are equal to target, add these four numbers to the answer ans and continue the first layer for loop next time; If the sum of the first number and the last three numbers is less than the target, continue the next for loop of the first layer. After adding the fixed second number, if the sum of the first two numbers and the first two numbers in the next array is greater than the target, directly exit the for loop of the second layer; If the sum of the first two numbers and the last two numbers in the next array is less than target, continue the second layer for loop. Time after modification
18ms, still didn't catch up with the solution. - On the basis of the first modification, the second modification adds at the beginning of the for loop of the first layer. First judge whether the number of current i positions is equal to the number of previous positions when i is greater than 0. If they are equal, it means that the first number in the quad is repeated. When the last three numbers remain unchanged, if the first number is repeated, it will inevitably lead to the repetition of the whole quad, Therefore, skip this repeated number, that is, continue the next layer 1 for loop; Similarly, at the beginning of the for loop of the second layer, first judge whether the number of current j positions is equal to the number of previous positions when J > i + 1. If so, skip this repeated number and continue the next for loop of the second layer. Time after modification
5ms, still didn't catch up with the solution. - In the third modification, on the basis of the first and second modifications, the following is added: de duplication of the third and fourth numbers, that is, in the while loop, if you encounter a quad that meets the meaning of the question, you can add it to ANS and use the while loop to de duplicate the numbers of left and right positions at the same time. If the numbers of left position and left+1 position are equal, then left + +, If the number of right positions and right-1 positions are equal, then right –; At the same time, it is found that when all four numbers are de duplicated, I don't need to go to hashset to de duplicate the quadruple. My current ans has no duplicate quadruple, so I modify ans to an ArrayList list, and finally return ans; In addition, add a judgment condition at the beginning. When the length of the num array is less than 4, it is impossible to have a qualified quad. At this time, an empty ans is returned directly. Time after modification
3ms, still didn't catch up with the solution. - The fourth modification. In fact, the third modification is the modification of the code of the problem solution. It is found that it is still 1ms worse than it. After my observation again, I found that the way of adding four numbers to the list is different,
The explanation of the question uses ans.add (arrays. Aslist (Num [i], Num [J], Num [left], Num [right]);
And I use
ans.add(new ArrayList(Arrays.asList(nums[i],nums[j],nums[left],nums[right])));
As a matter of fact, the explanation of the question must be better. I'm too delicious. I don't know I can write it like this.
code:
Directly put the code of version 4.
class Solution { public List<List<Integer>> fourSum(int[] nums, int target) { List<List<Integer>> ans = new ArrayList<>(); int len = nums.length; if (len<4){ return ans; } Arrays.sort(nums); for (int i = 0; i < len-3; i++) { if(i > 0 && nums[i] == nums[i-1]){ continue; } long before4_1 = (long) nums[i]+nums[i+1]+nums[i+2]+nums[i+3]; if (before4_1 > target){ break; }else if (before4_1 == target){ ans.add(Arrays.asList(nums[i],nums[i+1],nums[i+2],nums[i+3])); continue; } if ((long)nums[i]+nums[len-1]+nums[len-2]+nums[len-3] < target){ continue; } for (int j = i+1; j < len-2; j++) { if(j > i+1 && nums[j] == nums[j-1]){ continue; } int left = j+1,right = len-1; long pre = (long) nums[i]+nums[j],before4_2 = pre + nums[left]+nums[left+1]; if (before4_2 > target){ break; } if (pre +nums[right]+nums[right-1] < target){ continue; } while (left<right){ int cur = nums[left]+nums[right]; if (pre+cur<target){ left++; }else if (pre+cur>target){ right--; }else { ans.add(Arrays.asList(nums[i],nums[j],nums[left],nums[right])); while (left < right && nums[left] == nums[left + 1]) { left++; } left++; while (left < right && nums[right] == nums[right - 1]) { right--; } right--; } } } } return ans; } }
Time:
22. Bracket generation [medium question]
Idea:
- I don't know whether this is dynamic programming or recursive, but it feels similar to the problem of frog jumping steps.
- The hashset type ans is defined to store the answer of de duplication. The initial value is a pair of parentheses by default. From 2 to n, define a hashset type temp to store the parentheses that can be generated when the logarithm of parentheses is i; Traverse each bracket combination in ANS, and set the traversed bracket combination as str, then insert a pair of brackets after each element of str in turn (you can insert brackets in front of the whole str or after the whole str); Save the new bracket combination inserted into brackets into temp; After all the bracket combinations in ans have been traversed, update ans to all the bracket combinations in temp and continue the next time about
for loop of i. - After traversing n, the for loop exits. At this time, ans is converted to ArrayList type list and returned.
- The main problem-solving basis is to find the bracket combination of the current n according to the bracket combination of the previous n.
code:
class Solution { public List<String> generateParenthesis(int n) { Set<String> ans = new HashSet<>(); ans.add("()"); for (int i = 2; i <= n; i++) { Set<String> temp = new HashSet<>(); for (String str : ans){ for (int j = 0; j < str.length(); j++) { temp.add(str.substring(0,j)+"()"+str.substring(j)); } } ans = temp; } return new ArrayList<>(ans); } }
Time: