LeetCode-704,35,34,27:
704.二分查找
27.移除元素
思考:可以直接遍历,但是题目是二分查找,好呗
过程:使用双指针一个左一个右,取中间为mid,然后用target与mid对比,不断更新左右指针的位置
运行:第一次运行失败了,原因是写成了target>mid,无语住了
左闭右开版本:
class Solution {
public int search(int[] nums, int target) {
int l = 0;
int r = nums.length;
while(l<r){
int mid = (r-l)/2+l;
if(target<nums[mid]){
r = mid;
}else if(target>nums[mid]){
l = mid+1;
}else{
return mid;
}
}
return -1;
}
}
左闭右闭版本:
class Solution {
public int search(int[] nums, int target) {
int l = 0;
int r = nums.length-1;
while(l<=r){
int mid = (r-l)/2+l;
if(target<nums[mid]){
r = mid-1;
}else if(target>nums[mid]){
l = mid+1;
}else{
return mid;
}
}
return -1;
}
}
和上一题区别不大:
class Solution {
public int searchInsert(int[] nums, int target) {
int l = 0;
int r = nums.length-1;
while(l<=r){
int mid = (r-l)/2+l;
if(target<nums[mid]){
r = mid-1;
}else if(target>nums[mid]){
l = mid+1;
}else{
return mid;
}
}
// 为什么是l不是r?因为最后l==r的时候呢,if(target<nums[mid]),
// 那么r变小了,mid取代的应该是mid即l的位置;if(target>nums[mid]),那么l+1,所以取代的是mid+1,即依然是l的位置
return l;
}
}
没做出来。。。
待补充:分别寻找左边界和右边界,寻找左边界时,如果nums[mid] == target,需要继续向左边找,也就是需要继续搜寻mid左侧部分,所以先记录mid,然后再r = mid-1;
class Solution {
public int[] searchRange(int[] nums, int target) {
int l = 0;
int r = nums.length-1;
int lb = -1;
int rb = -1;
while(l<=r){
int mid = (r-l)/2+l;
if(nums[mid] == target){
lb = mid;
r = mid - 1;
}else if(nums[mid] > target){
r = mid - 1;
}else{
l = mid + 1;
}
}
l = 0;
r = nums.length-1;
while(l<=r){
int mid = (r-l)/2+l;
if(target == nums[mid]){
rb = mid;
l = mid + 1;
}else if(target < nums[mid]){
r = mid -1 ;
}else{
l = mid + 1;
}
}
return new int[]{lb,rb};
}
}
思路:相向双指针,或者快慢双指针
相向:
public int removeElement(int[] nums, int val) {
int l = 0;
int r = nums.length-1;
while (l<=r){
if(nums[l] !=val ){
l++;
}else {
nums[l] = nums[r];
r--;
}
}
return l;
}
快慢:这个没想出来。。。
class Solution {
public int removeElement(int[] nums, int val) {
int slow = 0;
for(int i = 0 ;i<nums.length;i++){
if(nums[i]!=val){
nums[slow] = nums[i];
slow++;
}
}
return slow;
}
}