二分查找
框架(注意要确定查找区间,还有尽量使用else if来保证细节)
int binarySearch(int[] nums, int target) {
int left = 0, right = ...;
while(...) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
...
} else if (nums[mid] < target) {
left = ...
} else if (nums[mid] > target) {
right = ...
}
}
return ...;
}
704. 二分查找
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target ,如果目标值存在返回下标,否则返回 -1 。
AC:
class Solution {
public int search(int[] nums, int target) {
int max = nums.length-1;
int min = 0;
int m;
while(min<max){
m = min + (max-min)/2; //m = min + (max - min) / 2; 没有“min+”也会超时
if(target == nums[m]){
return m;
}
if(target < nums[m]){
max = m-1;
}
else{
min = m+1; //后来改成只有下面+1,上面没有-1也超时了
}
}
return nums[min] == target ? min : -1;//这个直接写return就报错了。会有一些案例不通过
}
}
278 . 第一个坏版本
您是一名产品经理,目前正在领导一个团队开发新产品。不幸的是,您的产品的最新版本未通过质量检查。由于每个版本都是在前一个版本的基础上开发的,所以一个坏版本之后的所有版本也是坏的。
假设你有n 版本[1, 2, ..., n] ,你想找出第一个坏的,导致后面所有的都是坏的。
您将获得一个bool isBadVersion(version) 返回是否version 坏的 API。实现一个函数来查找第一个错误的版本。您应该尽量减少对 API 的调用次数。
解题思路:
此题考查的还是二分查找法:如果isBadVersion(mid)为true,则要查找的位置必然小于等于mid,即high = mid;反之若为false,则查找的位置要大于mid,即 low = mid + 1;二分区间不断缩短直至low = high,这时的low/high即为答案。
原来没有用二分,超出时间限制了。。题意是要用二分才能
/* The isBadVersion API is defined in the parent class VersionControl.
boolean isBadVersion(int version); */
public class Solution extends VersionControl {
public int firstBadVersion(int n) {
for(int i = 1; i<=n;i++){
if(isBadVersion(i)){
return i;
}
}
return 0;
}
}
AC:
/* The isBadVersion API is defined in the parent class VersionControl.
boolean isBadVersion(int version); */
public class Solution extends VersionControl {
public int firstBadVersion(int n) {
int min = 1;
int max = n;
int m;
while(min<max){
m = min + (max-min)/2;
if(isBadVersion(m)){
max = m;
}
else if(!isBadVersion(m)){
min = m+1;
}
}
return min;
}
}
双指针
189. 轮转数组
提示
中等1.7K
相关企业
给定一个整数数组 nums ,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。
示例 1:
输入: 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:
输入:nums = [-1,-100,3,99], k = 2
输出:[3,99,-1,-100]
解释:
向右轮转 1 步: [99,-1,-100,3]
向右轮转 2 步: [3,99,-1,-100]
提示:
1 <= nums.length <= 10 5
-2 31 <= nums[i] <= 2 31 - 1
0 <= k <= 10 5
AC:
使用反转数组的方法
class Solution {
public void rotate(int[] nums, int k) {
k %= nums.length;
reverse(nums, 0, nums.length - 1);
reverse(nums, 0, k - 1);
reverse(nums, k, nums.length - 1);
}
public void reverse(int[] nums, int start, int end) {
while (start < end) {
int temp = nums[start];
nums[start] = nums[end];
nums[end] = temp;
start += 1;
end -= 1;
}
}
}
作者:Esaka
链接:https://leetcode.cn/problems/rotate-array/solutions/790602/xuan-zhuan-shu-zu-by-esaka-f-vu56/
来源:力扣(LeetCode)
557. 反转字符串中的单词 III
简单525
相关企业
给定一个字符串 s ,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。
示例 1:
输入:s = "Let's take LeetCode contest" 输出:"s'teL ekat edoCteeL tsetnoc"
示例 2:
输入: s = "God Ding" 输出:"doG gniD"
提示:
1 <= s.length <= 5 * 10 4
s 包含可打印的 ASCII 字符。
s 不包含任何开头或结尾空格。
s 里 至少 有一个词。
s 中的所有单词都用一个空格隔开。
AC:
两种方法可以将字符数组转为字符串
String b = new String(a);
String b = String.valueOf(a);
用到反转数组
class Solution {
public String reverseWords(String s) {
char a[] = s.toCharArray();//将字符串转为字符数组
int start = 0;
for(int i = 0;i<a.length;i++){
if(a[i] == ' '){
int end = i-1;//空格前的字符下标为end
while(start<end){//反转字符数组
char temp = a[start];
a[start] = a[end];
a[end] = temp;
start++;
end--;
}
start = i+1;//start变为空格后一个字符下标
}
if(i == a.length - 1){//最后一个单词后面没有空格,要考虑这个情况
int end = i;
while(start<end){
char temp = a[start];
a[start] = a[end];
a[end] = temp;
start++;
end--;
}
}
}
// String b = new String(a);两种方法可以将字符数组转为字符串
String b = String.valueOf(a);
return b;
}
}