LeetCode 704. 二分查找
题目链接: LeetCode704.二分查找题目链接
思路
二分查找的主要思路在于目标元素 target是在 [ l e f t , r i g h t ] [left, right] [left,right] 还是 [ l e f t , r i g h t ) [left,right) [left,right) 区间。
- 如果 target在
[
l
e
f
t
,
r
i
g
h
t
]
[left,right]
[left,right] 区间的话,while 里面的语句
left==right
是要有的,因为在左闭右闭区间下,left==right
是有意义的。同时因为是左闭右闭区间,所以应该写成if(nums[middle]>target) right=middle-1
和if(nums[middle]<target) left=middle+1
。因为nums[middle]
不等于 target,所以无需 middle 这个点,同时我们是左闭右闭区间,所以我们新设置的 left 和 right 就需要如上的更新来更新到没有操作的区间了。 - 如果 target 是在
[
l
e
f
t
,
r
i
g
h
t
)
[left,right)
[left,right) 区间的话,while 里面的语句
left==right
是不能有的,因为在左闭右开区间内,这个语句是没有意义的。同时因为是左闭右开区间,所以应该写成if(nums[middle]>target) right=middle
和if(nums[target]<target) left=middle+1
。因为nums[middle]
不等于 target,所以无需 target 这个点,同时我们是左闭右开区间,所以我们新设置的 left 和 right 就需要如上的更新来更新到没有操作的区间了,因为右边是开区间,所以不需要进行减法操作也可以更新到没有操作的区间。
代码
左闭右闭区间下的代码:
class Solution {
public int search(int[] nums, int target) {
//第一种写法,左闭右闭区间
int size=nums.length;
int left=0;
int right=size-1;
while(left<=right)
{
int middle=left+(right-left)/2; //防止溢出
if(nums[middle]>target)
right=middle-1;
else if(nums[middle]<target)
left=middle+1;
else
return middle;
}
return -1;
}
}
左闭右开区间下的代码:
class Solution {
public int search(int[] nums, int target) {
//第二种写法,左闭右开区间
int size=nums.length;
int left=0;
int right=size;
while(left<right)
{
int middle=left+(right-left)/2;
if(nums[middle]>target)
right=middle;
else if(nums[middle]<target)
left=middle+1;
else
return middle;
}
return -1;
}
}
LeetCode 27. 移除元素
题目链接: LeetCode27.移除元素题目链接
思路
- 暴力做法:如果我们想要移除数组中的一个元素,那么就需要将这个元素后面的元素全部往前移动一位,所以根据暴力的做法,我们需要双重循环,一重循环用来遍历这个数组,另一重数组用来遍历到移除元素后进行元素的移除。
- 双指针的做法:当使用双指针时,我们可以设置一个快指针和一个慢指针,快指针用于数组元素的遍历,慢指针用于当快指针指向的元素不是移除元素时,使用慢指针所指向的位置存储这个值,然后慢指针向后移动一位。
代码
暴力做法的代码:
class Solution {
public int removeElement(int[] nums, int val) {
int n=nums.length;
for(int i=0;i<n;i++)
{
if(nums[i]==val)
{
for(int j=i+1;j<n;j++)
nums[j-1]=nums[j];
i--;
n--;
}
}
return n;
}
}
双指针做法的代码:
class Solution {
public int removeElement(int[] nums, int val) {
int slowindex=0;
int n=nums.length;
for(int fastindex=0;fastindex<n;fastindex++)
{
if(nums[fastindex]!=val)
nums[slowindex++]=nums[fastindex];
}
return slowindex;
}
}
LeetCode 977. 有序数组的平方
思路
使用双指针的做法,当我们对一个按照非递减顺序排序的整数数组进行平方后,我们可以发现,数组中的数应该是呈两边大中间小的形式。所以我们可以在两边各设置一个指针,进行比较,更大的值放入新数组的末尾。这样就可以得到一个非递减顺序的新数组了。
代码
class Solution {
public int[] sortedSquares(int[] nums) {
int n=nums.length-1;
int[] a=new int[n+1];
int left=0;
int right=n;
int k=n;
while(left<=right)
{
if(nums[left]*nums[left]>nums[right]*nums[right])
{
a[k--]=nums[left]*nums[left];
left++;
}
else
{
a[k--]=nums[right]*nums[right];
right--;
}
}
return a;
}
}