目录
一、有效的完全平方数
因为有大数,存在溢出,所以先除一个mid。而当num为1的时候,mid会取到0,不能当除数,所以特殊处理直接返回true。当flag等于mid的时候,还需要确认是否为整除。
class Solution {
public:
bool isPerfectSquare(int num) {
int low = 0;
int high = num;
while(low <= high){
int mid = low + (high - low) / 2;
if(mid == 0) return true;
int flag = num / mid;
if( flag == mid){
if(num % mid == 0) return true;
low = mid + 1;
}else if(flag > mid){
low = mid + 1;
}else{
high = mid - 1;
}
}
return false;
}
};
二、两个数组间的距离值
暴力解法
class Solution {
public:
int findTheDistanceValue(vector<int>& arr1, vector<int>& arr2, int d) {
int count = 0;
for(int i = 0; i < arr1.size(); i++){
int flag = 0;
for(int j = 0; j < arr2.size(); j++){
if(arr1[i] - arr2[j] > d || arr2[j] - arr1[i] > d){
flag++;
}else
break;
}
if(flag == arr2.size()){
count++;
}
}
return count;
}
};
二分法
自己写的,有bug,没有跑完所有案例,下面就放官方给出的答案。
class Solution {
public:
int findTheDistanceValue(vector<int>& arr1, vector<int>& arr2, int d) {
sort(arr2.begin(), arr2.end());
int cnt = 0;
for (auto &x: arr1) {
unsigned p = lower_bound(arr2.begin(), arr2.end(), x) - arr2.begin();
bool ok = true;
if (p < arr2.size()) {
ok &= (arr2[p] - x > d);
}
if (p - 1 >= 0 && p - 1 <= arr2.size()) {
ok &= (x - arr2[p - 1] > d);
}
cnt += ok;
}
return cnt;
}
};
作者:LeetCode-Solution
链接:https://leetcode.cn/problems/find-the-distance-value-between-two-arrays/solution/liang-ge-shu-zu-jian-de-ju-chi-zhi-by-leetcode-sol/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
三、移动零
方法一
找到非零便赋值,并记录位置,遍历完一遍后,然后再从第一个未赋值的地方进行赋0
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int j = 0;
for (int i = 0; i < nums.size(); i++) {
if(nums[i] != 0){
nums[j] = nums[i];
j++;
}
}
for (int i = j; i < nums.size();i++) {
nums[i] = 0;
}
}
};
双指针
low指向排序好部分的尾部,high一直往后面找非零数,找到就和low交换数值
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int low = 0;
int high = 0;
while(high < nums.size()){
if(nums[high] != 0){
int tmp = nums[high];
nums[high] = nums[low];
nums[low] = tmp;
low++;
}
high++;
}
}
};
四、两数之和 ||
二分法
找第二个数的时候,用二分法提高效率
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
int n = numbers.size();
for(int i = 0; i < n; i++){
int ans = target - numbers[i];
int low = i + 1;
int high = n - 1;
while(low <= high){
int mid = low + (high - low)/2;
if(numbers[mid] == ans){
return { i + 1, mid + 1};
}else if(numbers[mid] > ans){
high = mid - 1;
}else{
low = mid + 1;
}
}
}
return {-1 , -1};
}
};
双指针
因为是有序的,所有可以用两个指针分别指向两端,大了就大的后移,小了就小的前移
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
int n = numbers.size();
int low = 0;
int high = n - 1;
while(low <= high){
if(numbers[low] + numbers[high]== target){
return { low + 1, high + 1};
}else if(numbers[low] + numbers[high] > target){
high--;
}else{
low++;
}
}
return {-1 , -1};
}
};