力扣爆刷第96天之hot100五连刷66-70
文章目录
- 力扣爆刷第96天之hot100五连刷66-70
- 一、33. 搜索旋转排序数组
- 二、153. 寻找旋转排序数组中的最小值
- 三、4. 寻找两个正序数组的中位数
- 四、20. 有效的括号
- 五、155. 最小栈
一、33. 搜索旋转排序数组
题目链接:https://leetcode.cn/problems/search-in-rotated-sorted-array/description/?envType=study-plan-v2&envId=top-100-liked
思路:很简单,只需要先遍历找到数组旋转的中点,然后左右区间分别进行二分查找。
class Solution {public int search(int[] nums, int target) {if(nums.length == 1) return nums[0] == target ? 0 : -1;int slow = 0;for(int i = 1; i < nums.length; i++) {if(nums[i] > nums[slow]) {slow++;}else{int a = fun(nums, 0, slow, target);int b = fun(nums, i, nums.length-1, target);if(a != -1) return a;if(b != -1) return b;return -1;}}return fun(nums, 0, nums.length-1, target);}int fun(int[] nums, int left, int right, int target) {int a = left, b = right;while(left <= right) {int mid = left + (right - left) / 2;if(nums[mid] == target) {return mid;} else if(nums[mid] > target) {right = mid - 1;} else {left = mid + 1;}}return -1;}
}
二、153. 寻找旋转排序数组中的最小值
题目链接:https://leetcode.cn/problems/find-minimum-in-rotated-sorted-array/description/?envType=study-plan-v2&envId=top-100-liked
思路:仔细看会发现不管旋转多少次,旋转之后都是下面的这种情况,即左边整体高于右边,那么要寻找最小值,只需要二分逐段缩小区间,至于如何缩小,请注意nums[right]一定小于nums[left],求出中值后,如果nums[right]>nums[mid]就说明中值靠左,右边不要了,更新right=mid,如果nums[right]<=nums[mid]说明中值靠右,只有nums[mid]小于nums[right]才可能出现最小值,所以更新left=mid+1.
class Solution {public int findMin(int[] nums) {int left = 0, right = nums.length-1;while(left < right) {int mid = left + (right - left) / 2;if(nums[mid] < nums[right]) {right = mid;}else {left = mid + 1;}}return nums[left];}
}
三、4. 寻找两个正序数组的中位数
题目链接:https://leetcode.cn/problems/median-of-two-sorted-arrays/description/?envType=study-plan-v2&envId=top-100-liked
思路:本题只需要两个索引在两个数组上遍历,第三个索引作为计数使用,当数量达到中值时停止,期间使用两个变量记录中值附近的值,最后通过长度奇偶来确定结果。
class Solution {public double findMedianSortedArrays(int[] nums1, int[] nums2) {int m = nums1.length, n = nums2.length, len = m + n;int i = 0, j = 0;int left = -1, right = -1;for(int k = 0; k <= len / 2; k++) {left = right;if(i < m && (j >= n || nums1[i] < nums2[j])) {right = nums1[i++];}else {right = nums2[j++];}}if(len % 2 == 0) {return (left + right) / 2.0;}else{return right;}}
}
四、20. 有效的括号
题目链接:https://leetcode.cn/problems/valid-parentheses/description/?envType=study-plan-v2&envId=top-100-liked
思路:反向思维,如果是左括号,不添加左括号,而是添加右括号,然后利用栈。
class Solution {public boolean isValid(String s) {Deque<Character> stack = new LinkedList<>();for(int i = 0; i < s.length(); i++) {char c = s.charAt(i);if(c == '(') {stack.push(')');}else if(c == '[') {stack.push(']');}else if(c == '{') {stack.push('}');}else if(stack.isEmpty() || stack.peek() != c) {return false;}else{stack.pop();}}return stack.isEmpty();}
}
五、155. 最小栈
题目链接:https://leetcode.cn/problems/min-stack/description/?envType=study-plan-v2&envId=top-100-liked
思路:最小栈要求一个常规栈,能够在常数时间内返回最小值,其实很简单,栈是先进后出的,只要要进入的值大于栈顶值,要进入的值就没必要记录了,一定不是最小值,所以,使用两个栈,一个栈正常进栈出栈,另一个栈只让最小值或者栈顶元素进栈。
class MinStack {Deque<Integer> stack1 = new LinkedList<>();Deque<Integer> stack2 = new LinkedList<>();public MinStack() {stack2.push(Integer.MAX_VALUE);}public void push(int val) {stack1.push(val);stack2.push(Math.min(stack2.peek(), val));}public void pop() {stack1.pop();stack2.pop();}public int top() {return stack1.peek();}public int getMin() {return stack2.peek();}
}/*** Your MinStack object will be instantiated and called as such:* MinStack obj = new MinStack();* obj.push(val);* obj.pop();* int param_3 = obj.top();* int param_4 = obj.getMin();*/