二分查找:
Tips:
LeetCode704
这里的数组是有序的,看到有序数组就考虑二分查找
这里的难点在于边界条件的判断:
- while(</<=)
- right = mid - 1 / right = mid,这里错了会导致超时
- 左闭右闭
class Solution {
public int binarySearch(int[] nums, int target) {
int left = 0;
int right = nums.length - 1;
// 这里写的是左闭右闭
while (left <= right) {
int mid = (left + right) / 2;
if (nums[mid] > target) {
right = mid - 1;
} else if (nums[mid] < target) {
left = mid + 1;
} else {
return mid;
}
}
return -1;
}
}
- 左闭右开
class Solution {
public int binarySearch(int[] nums, int target) {
// 左闭右开区间
int left = 0;
int right = nums.length;
while (left < right) {
int mid = (left + right) / 2;
if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] > target) {
right = mid;
} else {
return mid;
}
}
return -1;
}
}
- 相关题目
- LeetCode35:
查找特定元素,如果没有返回该插入的下标,标准的二分查找,注意,left的位置即为应该插入的位置
class Solution {
public int searchInsert(int[] nums, int target) {
//[ , )
int left = 0;
int right = nums.length;
while(left<right){
int mid = (left+right)/2;
if(nums[mid] < target){
left = mid + 1;
}else if(nums[mid] > target){
right = mid;
}else{
return mid;
}
}
return left;
}
}
- LeetCode34:套壳的二分查找(注意判断边界条件)
class Solution {
public int[] searchRange(int[] nums, int target) {
int mid = binarySearch(nums,target);
if(mid != -1){
int left = mid;
int right = mid;
// 向右扩展边界
while (right + 1 < nums.length && nums[right + 1] == nums[mid]) {
right++;
}
// 向左扩展边界
while (left - 1 >= 0 && nums[left - 1] == nums[mid]) {
left--;
}
return new int[]{left,right};
}else{
return new int[]{-1, -1};
}
}
}
移除元素
Tips:
LeetCode27:移除特定值的元素
- 暴力解法
class Solution {
public int removeElement(int[] nums, int val) {
int size = nums.length;
for(int i = 0; i<nums.length; i++){
if(nums[i] == val){
for(int j = i+1; j<nums.length; j++){
nums[j-1] = nums[j];
}
size--;
}
}
return size;
}
}
- 快慢双指针解法
一个快指针,一个慢指针,实际上在一个数组中操作,但是逻辑上是两个数组
快指针:需要存在新数组中的值
慢指针:新数组的下标
class Solution {
public int removeElement(int[] nums, int val) {
int slow = 0;
//int size = nums.length;这里的size是多余的,返回slow就行
for( int fast = 0;fast<nums.length;fast++){
if(nums[fast] != val){
nums[slow++] = nums[fast];
}/*else{
size--;
}*/
}
//return size;
return slow;
}
}
- 相向双指针法
左指针和右指针,左指针表示新数组的下标,右指针表示当左指针指向的位置为val时,应该用什么数据来覆盖val
class Solution {
public int removeElement(int[] nums, int val) {
int left = 0;
int right = nums.length-1;
while(right>=0&&nums[right]==val){
right--;
}
while(left<=right){
if(nums[left] == val){
nums[left] = nums[right];
right--;
}
left++;
while(right>=0&&nums[right]==val){
right--;
}
}
return left;
}
}
- 相关题目
- LeetCode26:删除数组中的重复元素
fast用来遍历元素,并且判断元素是否重复
slow用来表示存储元素的位置,返回slow即可
class Solution {
public int removeDuplicates(int[] nums) {
int fast = 1;
int slow = 1;
while (fast < nums.length) {
if (nums[fast] != nums[fast - 1]) {
nums[slow] = nums[fast];
slow++;
}
fast++;
}
return slow;
}
}
有序数组的平方
加深对双指针的理解,靠近数组两端的绝对值大,因此从数组两端获取较大元素!
class Solution {
public int[] sortedSquares(int[] nums) {
int left = 0;
int right = nums.length - 1;
int[] result = new int[nums.length];
int k = result.length - 1;
while(left<=right){
int l = nums[left]*nums[left];
int r = nums[right]*nums[right];
if(l>=r){
result[k--] = l;
left++;
}else{
result[k--] = r;
right--;
}
}
return result;
}
}