这是我参与11月更文挑战的第4天,活动详情查看:2021最后一次更文挑战
367. 有效的完全平方数
给定一个 正整数 num ,编写一个函数,如果 num 是一个完全平方数,则返回 true ,否则返回 false 。
进阶:不要 使用任何内置的库函数,如 sqrt 。
示例 1:
输入:num = 16
输出:true
示例 2:
输入:num = 14
输出:false
提示:
- 1 <= num <= 2^31 - 1
解题思路
使用二分法,因为数字的平方是具有单调性的,因此我们可以选择[1,num]作为搜索区间,当mid的平方大于num时,我们在缩小区间为左边区间,反之当mid的平方小于num时,我们在缩小区间为右边区间。
代码
class Solution {
public:
bool isPerfectSquare(int num) {
int l(1),r(num);
while (l<=r){
int mid=(r-l)/2+l;
if ((long long )mid*mid==num)
return true;
else if ((long long )mid*mid<num)
l=mid+1;
else r=mid-1;
}
return false;
}
};
977. 有序数组的平方
给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
- 示例 1:
输入:nums = [-4,-1,0,3,10] 输出:[0,1,9,16,100] 解释:平方后,数组变为 [16,1,0,9,100] 排序后,数组变为 [0,1,9,16,100]
- 示例 2:
输入:nums = [-7,-3,2,3,11] 输出:[4,9,9,49,121]
解题思路
先找出正负数的分界点,使用两个指针分别指向正数部分和负数部分,然后不断比较两个指针指向的元素,选出较小的那个元素的平方加入结果,因为在负数部分元素的绝对值是向左递减的,而正数部分的绝对值是向右递增的,因此正负数的指针是一个向左一个向右的
代码
class Solution {
public int[] sortedSquares(int[] nums) {
int n=nums.length;
int[] res=new int[n];
int rp=0;int i=0;
for(;i<n;i++)
if(nums[i]>=0)
break;
int neg=i-1,pos=i;
while(rp<n)
{
if(pos>=n||neg>=0&&Math.abs(nums[neg])<nums[pos])
{
res[rp]=nums[neg]*nums[neg];
neg--;
}else {
res[rp]=nums[pos]*nums[pos];
pos++;
}
rp++;
}
return res;
}
}