每日算法刷题Day4 5.12:leetcode数组4道题,用时1h
7. 704.二分查找
704. 二分查找 - 力扣(LeetCode)
思想
二分模版题
代码
c++:
class Solution {
public:int search(vector<int>& nums, int target) {int n=nums.size();int left=0,right=n-1;int res=-1;while(left<=right){int mid=left+((right-left)>>1);if(nums[mid]==target) return mid;else if(nums[mid]>target){right=mid-1;}else{left=mid+1;}}return res;}
};
python:
class Solution:def search(self, nums: List[int], target: int) -> int:n = len(nums)left, right = 0, n - 1res = -1while left <= right:mid = left + ((right - left) >> 1)if nums[mid] == target:return midelif nums[mid] > target:right = mid - 1else:left = mid + 1return res
8. 35.搜索插入位置
35. 搜索插入位置 - 力扣(LeetCode)
思想
还是二分查找,当时相对于上一题,题目条件变为“如果目标值不存在于数组中,返回它将会被按顺序插入的位置。”,所以要在初始化res=n
(数组里面查找不到肯定插入末端)(这个点一开始写没想好),同时查找过程中更新res
代码
c++:
class Solution {
public:int searchInsert(vector<int>& nums, int target) {int n = nums.size();int left = 0, right = n - 1;int res = n;while (left <= right) {int mid = left + ((right - left) >> 1);if (nums[mid] == target) {return mid;} else if (nums[mid] > target) {right = mid - 1;res = mid;} else {left = mid + 1;}}return res;}
};
python:
class Solution:def searchInsert(self, nums: List[int], target: int) -> int:n = len(nums)left, right = 0, n - 1res = nwhile left <= right:mid = left + ((right - left) >> 1)if nums[mid] == target:return midelif nums[mid] > target:right = mid - 1res = midelse:left = mid + 1return res
9. 69.x的平方根
思想
1.找x的平方根,不利用sqrt函数,就是从[0,x]
找,因为有序,可以优化为二分查找,跟第8题一样
2.非负整数x,包括0,left从0开始
3.c++中mid*mid
要变成long long,但是python没有这个问题
代码
c++:
class Solution {
public:int mySqrt(int x) {// return (int)sqrt(x);int left = 0, right = x, res = 1;while (left <= right) {int mid = left + ((right - left) >> 1);if ((long long)mid * mid == x)return mid;else if ((long long)mid * mid < x) {left = mid + 1;res = mid;} else {right = mid - 1;}}return res;}
};
python:
class Solution:def mySqrt(self, x: int) -> int:left, right = 0, xres = 0while left <= right:mid = left + ((right - left) >> 1)if mid * mid == x:return midelif mid * mid < x:res = midleft = mid + 1else:right = mid - 1return res
相似题
367. 有效的完全平方数 - 力扣(LeetCode)
10 27.移除元素(简单,学习,双指针)
27. 移除元素 - 力扣(LeetCode)
思想
维护区间[0mleft)
不包含val,所以长度为left
1.法一同向双指针:
左指针left为下一个要赋值的位置,右指针为当前待处理位置,如果不等于val,则赋值到left位置,left++。循环退出条件为right>=n
2.法二双向双指针:
左指针left为当前待处理位置,若值等于val,则把右指针right的值赋值过去,且right–,否则left++。循环退出条件left>right
3.法一优势在于维护原先相对顺序,而法二优势在于没有重复赋值
代码
法一:
c++:
class Solution {
public:int removeElement(vector<int>& nums, int val) {int n = nums.size();int left = 0;for (int right = 0; right < n; ++right) {if (nums[right] != val) {nums[left] = nums[right];left++;}}return left;}
};
python:
class Solution:def removeElement(self, nums: List[int], val: int) -> int:n = len(nums)left = 0for right in range(n):if nums[right] != val:nums[left] = nums[right]left += 1return left
法二:
c++:
class Solution {
public:int removeElement(vector<int>& nums, int val) {int n = nums.size();int left = 0, right = n - 1;while (left <= right) {if (nums[left] == val) {nums[left] = nums[right];right--;} else {left++;}}return left;}
};
python:
class Solution:def removeElement(self, nums: List[int], val: int) -> int:n = len(nums)left, right = 0, n - 1while left <= right:if nums[left] == val:nums[left] = nums[right]right -= 1else:left += 1return left