澄o的第一天代码随想录记录
自己看到这道题 之前见过两三次 自己慢慢的复述出来思路就写出来大概的二分算法
代码随想录的答案精化算法细节 我在自己的代码里也加上
记得第一次看二分算法很难 一点都不懂 但是既然选择码就要坚持走下去 果然看了两三遍就会了 希望自己可以多拓展多敲敲 多回头复习巩固一下
Java代码:
class Solution{
public int search(int[] nums, int target){
//避免当target小于nums[0] nums[nums.length - 1]时多次运算
//特殊规避情况
if(target < nums[0] || target > nums[nums.length - 1]){
return -1;
}
int left = 0,right = nums.length - 1;
//左闭右闭
while(left <= right){
int mid = left + ((right - left) >> 1);//防止数据过大溢出
if(nums[mid] == target){
return mid;
}else if(nums[mid] < target){
left = mid + 1;
} else{
right = mid - 1;
}
}
return -1;//没找到
}
}
27. 移除元素
第一下想到暴力解法 遍历数组找到val 再用j = i + 1的j指针(下一个元素)直接覆盖nums[i](当前元素值) 更新位置也删除了元素 需要把数组长度n-1保持元素数目一致 同样把i也减一
搬用gpt的解释
i--
的目的是为了确保在当前位置的元素被覆盖后,外层循环能够重新检查这个新覆盖的元素。这是因为在内层循环中,你将后面的元素向前移动来覆盖当前等于 val
的元素,这意味着当前索引 i
的位置现在有了新的值,这个新值可能也需要被移除。
/*假设数组 nums
是 [3, 2, 2, 3]
,并且我们要移除所有值为 2
的元素
- 第一次循环,
i = 0
,nums[0] = 3
,不等于val
(假设val = 2
),所以不做任何操作。 - 第二次循环,
i = 1
,nums[1] = 2
,等于val
,所以我们进入内层循环。 - 在内层循环中,我们将
nums[2]
(值为2
)移动到nums[1]
的位置,覆盖了原来的2
。现在nums
变成了[3, 3, 2]
。 - 因为我们执行了
n--
,所以数组的有效长度减少了,n
从4
变成了3
。 - 然后我们执行
i--
,这样i
从2
变回1
。这是因为nums[1]
现在有了新的值(原来的nums[2]
),这个值可能也需要被移除。
如果没有 i--
,循环将继续检查下一个元素(nums[2]
),而不会重新检查 nums[1]
的新值,这可能会导致漏掉需要移除的元素。
因此,i--
确保了每个新覆盖的元素都能被重新检查,以确保所有等于 val
的元素都被移除*/
Java代码:
class Solution {
public int removeElement(int[] nums, int val) {
int n = nums.length;
for(int i = 0; i < n; i++){
if(val == nums[i]){//若发现删除元素 就把数组集体往前移动一位
for(int j = i + 1;j < n; j++){
nums[j - 1] = nums[j];
}
i--;//因为下标i的元素也往前移动一位了 所以i--回退1位
n--;//此时数组大小再-1
}
}
return n;//返回数组长度
}
}
双指针?
不会做捏 看看代码随想录
双指针法(快慢指针法): 通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。
针对这道题分为快慢指针和相向指针法
快慢指针分别指:快指针:寻找新数组元素,新数组指不含有目标元素的数组
慢指针:指向更新 新数组下标的位置
个人认为快慢指针用于覆盖元素和位置移动
Java代码:
class Solution {
public int removeElement(int[] nums, int val) {
//快慢指针
int slowindex = 0;
for(int fastindex = 0; fastindex < nums.length; fastindex++){
//如果fastindex对应数组的元素值是val 则跳过当前元素下标并继续下一个元素
//如果fastindex对应数组元素值不是val 则跳过当前元素
//nums[slowindex++] = nums[fastindex];的意义是
//用nums[fastindex](快指针对应元素值)的值覆盖当前slowindex下标对应元素值 完成值交换
//再给slowindex++
//把慢指针右移一位 完成位置右移
if(val != nums[fastindex]){
nums[slowindex++] = nums[fastindex];
}
}
return slowindex;
}
}
相向指针法
看了一下gpt的解释 加上自己的思考 捋清楚思路了 先把right指针移动到从右开始第一个不是val的元素上 如果nums[right] == val 那就直接right-- 删除此位置和元素 豁然开朗捏
left和right的内部操作可以理解
Java代码:
class Solution {
//个人理解 不如快慢指针清晰 但是尝试接受双指针
public int removeElement(int[] nums, int val) {
int left = 0;
int right = nums.length - 1;
while(right >= 0 && nums[right] == val) right--;
//把right指针移到从右数第一个值不为val的位置 例子[3 2 4 2] val == 2
while(left <= right){
if(nums[left] == val){//left位置的元素需要移除
nums[left] = nums[right];//把right位置的元素移到left
//再把right下标位置删除 right--
right--;
}
left++;//left右移
while(right >= 0 && nums[right] == val) right--;
////将right移到从右数第一个值不为val的位置
}
return left;
}
}
OK了结束打卡 去看看左神的算法课~