第一天 二分查找 难度简单279收藏分享切换为英文接收动态反馈
给定一个 n
个元素有序的(升序)整型数组 nums
和一个目标值 target
,写一个函数搜索 nums
中的 target
,如果目标值存在返回下标,否则返回 -1
。示例 1:
1 2 3 输入: nums = [-1,0,3,5,9,12], target = 9 输出: 4 解释: 9 出现在 nums 中并且下标为 4
示例 2:
1 2 3 输入: nums = [-1,0,3,5,9,12], target = 2 输出: -1 解释: 2 不存在 nums 中因此返回 -1
提示:
你可以假设 nums
中的所有元素是不重复的。
n
将在 [1, 10000]
之间。
nums
的每个元素都将在 [-9999, 9999]
之间。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class Solution { public int search (int [] nums, int target) { return getTarget(nums, target, 0 , nums.length-1 ); } public int getTarget (int [] nums, int target, int begin, int end) { if (end < begin) { return -1 ; } int temp = begin + (end-begin)/2 ; if (nums[temp] == target){ return temp; }else { if (nums[temp] > target){ end = temp - 1 ; } if (nums[temp] < target){ begin = temp + 1 ; } return getTarget(nums, target, begin, end); } } }
难度简单357收藏分享切换为英文接收动态反馈
你是产品经理,目前正在带领一个团队开发新的产品。不幸的是,你的产品的最新版本没有通过质量检测。由于每个版本都是基于之前的版本开发的,所以错误的版本之后的所有版本都是错的。
假设你有 n
个版本 [1, 2, ..., n]
,你想找出导致之后所有版本出错的第一个错误的版本。
你可以通过调用 bool isBadVersion(version)
接口来判断版本号 version
是否在单元测试中出错。实现一个函数来查找第一个错误的版本。你应该尽量减少对调用 API 的次数。
示例 1:
1 2 3 4 5 6 7 输入:n = 5, bad = 4 输出:4 解释: 调用 isBadVersion(3) -> false 调用 isBadVersion(5) -> true 调用 isBadVersion(4) -> true 所以,4 是第一个错误的版本。
示例 2:
提示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public class Solution extends VersionControl { public int firstBadVersion (int n) { return getFirstBadVersion(1 , n); } public int getFirstBadVersion (int start, int end) { int mid = start + (end-start)/2 ; if (!isBadVersion(mid)) { start = mid+1 ; } else { if (!isBadVersion(mid-1 )){ return mid; }else { end = mid-2 ; } } return getFirstBadVersion(start, end); } }
难度简单976收藏分享切换为英文接收动态反馈
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 O(log n)
的算法。
示例 1:
1 2 输入: nums = [1,3,5,6], target = 5 输出: 2
示例 2:
1 2 输入: nums = [1,3,5,6], target = 2 输出: 1
示例 3:
1 2 输入: nums = [1,3,5,6], target = 7 输出: 4
示例 4:
1 2 输入: nums = [1,3,5,6], target = 0 输出: 0
示例 5:
1 2 输入: nums = [1], target = 0 输出: 0
提示:
1 <= nums.length <= 104
-104 <= nums[i] <= 104
nums
为无重复元素 的升序 排列数组
-104 <= target <= 104
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class Solution { public int searchInsert (int [] nums, int target) { int start = 0 ; int end = nums.length - 1 ; int mid = 0 ; while (start <= end){ mid = start + (end-start)/2 ; if (nums[mid] == target) { return mid; } if (nums[mid] > target) { end = mid - 1 ; } if (nums[mid] < target) { start = start + 1 ; } } if (nums[mid] > target){ return mid; }else { return mid + 1 ; } } }
第二天 双指针 难度简单255收藏分享切换为英文接收动态反馈
给你一个按 非递减顺序 排序的整数数组 nums
,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
示例 1:
1 2 3 4 输入:nums = [-4,-1,0,3,10] 输出:[0,1,9,16,100] 解释:平方后,数组变为 [16,1,0,9,100] 排序后,数组变为 [0,1,9,16,100]
示例 2:
1 2 输入:nums = [-7,-3,2,3,11] 输出:[4,9,9,49,121]
提示:
1 <= nums.length <= 104
-104 <= nums[i] <= 104
nums
已按 非递减顺序 排序
进阶:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Solution { public int [] sortedSquares(int [] nums) { int start = 0 ; int end = nums.length - 1 ; int [] arr = new int [nums.length]; int index = nums.length-1 ; while (start <= end) { if (nums[start]*nums[start]<nums[end]*nums[end]){ arr[index] = nums[end]*nums[end]; end--; }else { arr[index] = nums[start]*nums[start]; start++;; } index--; } return arr; } }
难度中等1037收藏分享切换为英文接收动态反馈
给定一个数组,将数组中的元素向右移动 k
个位置,其中 k
是非负数。
进阶:
尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。
你可以使用空间复杂度为 O(1) 的 原地 算法解决这个问题吗?
示例 1:
1 2 3 4 5 6 输入: nums = [1,2,3,4,5,6,7], k = 3 输出: [5,6,7,1,2,3,4] 解释: 向右旋转 1 步: [7,1,2,3,4,5,6] 向右旋转 2 步: [6,7,1,2,3,4,5] 向右旋转 3 步: [5,6,7,1,2,3,4]
示例 2:
1 2 3 4 5 输入:nums = [-1,-100,3,99], k = 2 输出:[3,99,-1,-100] 解释: 向右旋转 1 步: [99,-1,-100,3] 向右旋转 2 步: [3,99,-1,-100]
提示:
1 <= nums.length <= 2 * 104
-231 <= nums[i] <= 231 - 1
0 <= k <= 105
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Solution { public void rotate (int [] nums, int k) { int n = nums.length; k %= n; reverse(nums, 0 , n - 1 ); reverse(nums, 0 , k - 1 ); reverse(nums, k, n - 1 ); } private void reverse (int [] nums, int start, int end) { while (start < end) { int temp = nums[start]; nums[start++] = nums[end]; nums[end--] = temp; } } }
第三天 双指针 难度简单1132收藏分享切换为英文接收动态反馈
给定一个数组 nums
,编写一个函数将所有 0
移动到数组的末尾,同时保持非零元素的相对顺序。
示例:
1 2 输入: [0,1,0,3,12] 输出: [1,3,12,0,0]
说明 :
必须在原数组上操作,不能拷贝额外的数组。
尽量减少操作次数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Solution { public void moveZeroes (int [] nums) { int start = 0 ; int end = 1 ; int temp; while (start < nums.length-1 && end < nums.length) { if (nums[start] == 0 && nums[end] != 0 ) { temp = nums[start]; nums[start] = nums[end]; nums[end] = temp; start++; end++; } else { if (nums[start] != 0 ) { start++; end = start; } if (nums[end] == 0 ) { end++; } } } } }
难度简单545收藏分享切换为英文接收动态反馈
给定一个已按照 升序排列 的整数数组 numbers
,请你从数组中找出两个数满足相加之和等于目标数 target
。
函数应该以长度为 2
的整数数组的形式返回这两个数的下标值。 numbers
的下标 从 1 开始计数 ,所以答案数组应当满足 1 <= answer[0] < answer[1] <= numbers.length
。
你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。
示例 1:
1 2 3 输入:numbers = [2,7,11,15], target = 9 输出:[1,2] 解释:2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。
示例 2:
1 2 输入:numbers = [2,3,4], target = 6 输出:[1,3]
示例 3:
1 2 输入:numbers = [-1,0], target = -1 输出:[1,2]
提示:
2 <= numbers.length <= 3 * 104
-1000 <= numbers[i] <= 1000
numbers
按 递增顺序 排列
-1000 <= target <= 1000
仅存在一个有效答案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Solution { public int [] twoSum(int [] numbers, int target) { for (int i = 0 , j = numbers.length - 1 ; i < j;) { int sum = numbers[i] + numbers[j]; if (sum == target) { return new int [] {i + 1 , j + 1 }; }else if (sum > target) { j--; } else { i++; } } return null ; } }