携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第17天,点击查看活动详情 >>
每日三刷,剑指千题
计划简介:
- 每日三题,以中等题为主,简单题为辅进行搭配。保证质量题1道,数量题3道。
- 每日早通勤在LeetCode手机端选题,思考思路,没答案的直接看题解。
- 每日中午进行编码,时间控制在一小时之内。
- 下班前半小时进行整理总结,并发布到掘金每日更文活动。
说明:
- 基于以前的刷题基础,本次计划以中等题为主,大部分中等题都可以拆分为多个简单题,所以数量保证3,质量保证一道中等题即可。
- 刷题顺序按照先刷链表、二叉树、栈、堆、队列等基本数据结构,再刷递归、二分法、排序、双指针等基础算法,最后是动态规划、贪心、回溯、搜索等复杂算法。
- 刷题过程中整理相似题型,刷题模板。
- 目前进度 139/1000 。
[167]两数之和 II - 输入有序数组
给你一个下标从 1 开始的整数数组 numbers ,该数组已按 非递减顺序排列 ,请你从数组中找出满足相加之和等于目标数 target 的两个数。如果设这两个数分别是 numbers[index1] 和 numbers[index2] ,则 1 <= index1 < index2 <= numbers.length 。
以长度为 2 的整数数组 [index1, index2] 的形式返回这两个整数的下标 index1 和 index2。
你可以假设每个输入 只对应唯一的答案 ,而且你 不可以 重复使用相同的元素。
你所设计的解决方案必须只使用常量级的额外空间。
示例 1:
输入:numbers = [2,7,11,15], target = 9
输出:[1,2]
解释:2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。返回 [1, 2] 。
解析
Code
class Solution {
public int[] twoSum(int[] numbers, int target) {
int[] ans = new int[2];
// 如何更快的寻找第二个数
for (int i = 0; i < numbers.length; i++) {
int first = numbers[i];
int left = i + 1; // 左端点
int right = numbers.length - 1; // 右
while (left <= right) {
int mid = (right - left) / 2 + left;
if (numbers[mid] + first == target) {
ans[0] = i + 1;
ans[1] = mid + 1;
return ans;
} else if (numbers[mid] + first > target) {
// 修改端点
right = mid - 1;
} else {
left = mid + 1;
}
}
}
return ans;
}
}
[209]长度最小的子数组
给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度 。 如果不存在符合条件的子数组,返回 0 。
示例 1:
输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
解析
>= target 坑死
Code
class Solution {
public int minSubArrayLen(int target, int[] nums) {
// 练习 前缀和 + 二分 (双指针也可)
int ans = Integer.MAX_VALUE;
if (nums.length == 0) return 0;
// 构建 前缀和 单调递增
int[] sum = new int[nums.length + 1];
for (int i = 1; i < sum.length; i++) {
sum[i] = nums[i - 1] + sum[i - 1];
}
for (int i = 0; i < sum.length; i++) {
int s = sum[i];
// 在前缀和数组 二分查找
int left = 0, right = i;
while (left < right) {
int mid = (left + right + 1) / 2;
if (sum[mid] <= s - target) {
left = mid;
} else {
right = mid - 1;
}
}
if (sum[right] <= s - target) {
ans = Math.min(ans, i - right);
}
}
return ans == Integer.MAX_VALUE ? 0 : ans;
}
}
[704]二分查找
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
示例 1:
输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4
解析
二分模板,记住int mid = (left+right+1)/2;
Code
class Solution {
public int search(int[] nums, int target) {
int left = 0,right = nums.length -1;
while (left<=right){
int mid = (left+right+1)/2;
if (nums[mid] == target){
return mid;
}else if (nums[mid] < target){
left = mid + 1;
}else {
right = mid -1;
}
}
return -1;
}
}
\