重新刷题Day1
其实之前有刷过一次随想录了,还有一些每日一题 ,但是总是断断续续的 没有形成良好的习惯 ,或者说每次刷着都是草草了事 ,刷过也忘了 ,今日一会想大概从去年十一月底就没刷了 三个月过去 又忘得差不多了,临近秋招,从三月开始 ,重新刷题!改变心态! 冲冲!
二分查找
-
二分法是非常常见的算法 会应用到各种类型的题目当中去 ,二分法有俩种写法
一种是左闭右闭区间,另一种是左闭右开区间
- while (left <= right) 因为left == right是有意义的,所以使用 <=。if (nums[middle] > target) right 要赋值为 middle - 1,因为当前这个nums[middle]一定不是target,那么接下来要查找的左区间结束下标位置就是 middle - 1。ps 刚才自己做题的时候就没写 -1和 +1直接赋值middle了 麻!
- while (left < right),这里使用 < ,因为left == right在区间[left, right)是没有意义的。if (nums[middle] > target) right 更新为 middle,因为当前nums[middle]不等于target,去左区间继续寻找,而寻找区间是左闭右开区间,所以right更新为middle,即:下一个查询区间不会去比较nums[middle]
-
代码:
-
var search = function(nums, target) { // right是数组最后一个数的下标,num[right]在查找范围内,是左闭右闭区间 let mid, left = 0, right = nums.length - 1; // 当left=right时,由于nums[right]在查找范围内,所以要包括此情况 while (left <= right) { // 位运算 + 防止大数溢出 mid = left + ((right - left) >> 1); // 如果中间数大于目标值,要把中间数排除查找范围,所以右边界更新为mid-1;如果右边界更新为mid,那中间数还在下次查找范围内 if (nums[mid] > target) { right = mid - 1; // 去左面闭区间寻找 } else if (nums[mid] < target) { left = mid + 1; // 去右面闭区间寻找 } else { return mid; } } return -1; }; var search = function(nums, target) { // right是数组最后一个数的下标+1,nums[right]不在查找范围内,是左闭右开区间 let mid, left = 0, right = nums.length; // 当left=right时,由于nums[right]不在查找范围,所以不必包括此情况 while (left < right) { // 位运算 + 防止大数溢出 mid = left + ((right - left) >> 1); // 如果中间值大于目标值,中间值不应在下次查找的范围内,但中间值的前一个值应在; // 由于right本来就不在查找范围内,所以将右边界更新为中间值,如果更新右边界为mid-1则将中间值的前一个值也踢出了下次寻找范围 if (nums[mid] > target) { right = mid; // 去左区间寻找 } else if (nums[mid] < target) { left = mid + 1; // 去右区间寻找 } else { return mid; } } return -1; };
移除元素
-
刚开始觉得自己可以瞬间秒杀 不使用暴力方法 没想到写了半小时 还不是双指针 不知道自己之前刷题怎么刷过去的 附上自己的解法 勿喷。
var removeElement = function(nums, val) { let len = nums.length nums.sort((a,b) => a-b) let res = 0 let left = 0 let right = len - 1 while(left < len){ if(nums[left] !== val){ left++ continue } if(nums[left] == val){ res++ nums[left] = nums[right] right-- left++ } } return len - res };
- 先排序 然后left查找删除元素 使用res计数,如果val后面还有别的元素 复制到前面去,最后直接返回删除后的元素个数
-
暴力解法 双循环
-
var removeElement = function(nums, val) { let len = nums.length for(let i = 0 ; i < len ; i++){ if(nums[i] === val ){ for(let j = i+ 1 ; j < len ; j++){ nums[j-1] = nums[j] } i-- len-- } } return len };
-
-
双指针:
-
一快一慢,快指针寻找新数组的元素 ,新数组就是不含有目标元素的数组,慢指针就是要找要更新的位置
-
var removeElement = (nums, val) => { let k = 0;//慢指针,i就是快指针 for(let i = 0;i < nums.length;i++){ if(nums[i] != val){ nums[k++] = nums[i] } } return k; };
-
-