LeetCode算法刷题|第一天|704二分查找、27移除元素、977有序数组的平方
LeetCode704二分查找
思路:将数组拆分为两部分,取中间值与目标值比较,中间值如果大于目标值,再在左边区间继续寻找,反之 在右边区间寻找。
前提:1、数组为有序数组 2、数组中没有重复元素。
难点:区间的定义不清楚 ==> 常见解决思路:1、左闭右闭 2、左闭右开。
1、左闭右闭
//第一种:左闭右闭写法
//定义一个左指针、右指针
int left = 0,int right = nums.length - 1;
//判断中间值和目标值是否相等
//第一种写法
while (left <= right) { //左闭右闭体现在这里
int middle = (left + right) / 2;
if (nums[middle] < target) {
left = middle + 1;
} else if (nums[middle] > target) {
right = middle - 1;
} else {
return middle;
}
}
//未找到目标值
return -1;
2、左闭右开
//第二种:左闭右开写法
//定义左指针、右指针
int left = 0, right = nums.length; //右指针的范围调整
while (left < right) { //[left,right) --> [1,1)
int middle = (left + right) / 2; //中间指针,用于和目标值比较
if (nums[middle] < target) { //1、中间值小于目标值
left = middle + 1; //左区间闭环,middle元素已经和区间左边的值做比较,所以左指针应加1
} else if (nums[middle] > target) { //2、中间值大于目标值
right = middle; //右区间打开,middle元素没有和区间右边的值做比较,所以右指针不用加减
} else { //3、中间值等于目标值
return middle;
}
}
return -1;
总结
nums.length 和nums,length-1主要用于取值,遍历等;需要考虑数组0为元素和最高位蒜素是否需要取到的情况。
创建一个新的数组直接nums.length渠道数组的大小。
LeetCode27移除元素
题目链接:题目链接
文章讲解:点击跳转-文章讲解
视频讲解:点击跳转-视频讲解
思路:找到重复的元素,删除就好。
方法:1、暴力求解 2、双指针法
//第一种方法:暴力破解方法
int sizeNums = nums.length;
for (int i = 0; i < sizeNums; i++) { //第一层:遍历数组中的元素
//如果元素重复,通过覆盖的方式移除
if (nums[i] == val) {
for (int j = i + 1; j < sizeNums; j++) { //第二层:覆盖元素
nums[j - 1] = nums[j];
}
//移除元素后,下标向前移一位;数组的大小减一
i--;
sizeNums--;
}
}
return sizeNums;
- 时间复杂度O(n²)*
//第二种方法:快慢指针
int slowIndex = 0; //定义指向更新,新数组下标的位置
//在一个for循环下完成暴力破解中两个for循环的事情
for (int fastIndex = 0; fastIndex < nums.length; fastIndex++) {
if (nums[fastIndex] != val) {
nums[slowIndex] = nums[fastIndex];
slowIndex++;
}
}
//返回新数组的长度
return slowIndex;
- 时间复杂度O(n)
//双指针法-相向指针法2
int left = 0; //更新数组的下标
int right = nums.length - 1;
while (left <= right) {
if (nums[left] == val) {
nums[left] = nums[right];
right--;
} else {
left++;
}
}
//返回数组下标
return left;
//双指针-相向指针方法
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;
总结
指针的加减要注意变量使用在前还是增减在前
LeetCode977有序数组的平方
思路:先把数组平方,然后排序。
方法:1、暴力排序 2、双指针法
//方法2:双指针法,新建一个数组,将左右指针比较得到的最大值插入到新数组的末尾。
int left = 0;
int right = nums.length - 1;
int[] result = new int[nums.length];
int index = result.length - 1;
while (left <= right) {
if (nums[left] * nums[left] > nums[right] * nums[right]) {
result[index] = nums[left] * nums[left];
index--;
left++;
} else{
result[index] = nums[right] * nums[right];
index--;
right--;
}
}
return result;
- 此时的时间复杂度为O(n),相对于暴力排序的解法O(n + nlog n)还是提升不少的。
总结
暴力排序时,使用了Java语言的API。
双指针排序让人爽到了。