代码随想录算法训练营Day01

二分查找:

Tips:
LeetCode704
这里的数组是有序的,看到有序数组就考虑二分查找
这里的难点在于边界条件的判断:

  1. while(</<=)
  2. right = mid - 1 / right = mid,这里错了会导致超时
  1. 左闭右闭
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;
	}
}
  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;
	}
}
  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:移除特定值的元素

  1. 暴力解法
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;
	}
}
  1. 快慢双指针解法

一个快指针,一个慢指针,实际上在一个数组中操作,但是逻辑上是两个数组
快指针:需要存在新数组中的值
慢指针:新数组的下标

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;
	}
}
  1. 相向双指针法

左指针和右指针,左指针表示新数组的下标,右指针表示当左指针指向的位置为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;
	}
}
  1. 相关题目
  • 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;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值