633. Sum of Square Numbers (Easy)
Leetcode / 力扣
Input: 5
Output: True
Explanation: 1 * 1 + 2 * 2 = 5
题目描述:判断一个非负整数是否为两个整数的平方和。
可以看成是在元素为 0~target 的有序数组中查找两个数,使得这两个数的平方和为 target,如果能找到,则返回 true,表示 target 是两个整数的平方和。
本题和 167. Two Sum II - Input array is sorted 类似,只有一个明显区别:一个是和为 target,一个是平方和为 target。本题同样可以使用双指针得到两个数,使其平方和为 target。
本题的关键是右指针的初始化,实现剪枝,从而降低时间复杂度。设右指针为 x,左指针固定为 0,为了使 02 + x2 的值尽可能接近 target,我们可以将 x 取为 sqrt(target)。
因为最多只需要遍历一次 0~sqrt(target),所以时间复杂度为 O(sqrt(target))。又因为只使用了两个额外的变量,因此空间复杂度为 O(1)。
代码展示:本代码实现与原文不同,原题是找到一个符合要求的结果后,程序就停止执行,而本题代码实现是找到所有符合要求的结果,并将其添加到list集合中,然后进行输出。
import java.util.ArrayList;
import java.util.List;
public class DoublePointer2_twoSquareSum {
public static void main(String[] args) {
int target = 100,i=0,j;
int index_first = 0;
//定义两个集合,用于存储全部符合条件的结果
List list_first = new ArrayList();
List list_end = new ArrayList();
//剪枝操作,降低时间复杂度,对目标数进行开平方
int index_end = (int)Math.sqrt(target);
//双指针进行遍历
while (index_first<index_end){
int temp = index_first*index_first + index_end *index_end;
if ( temp == target ){
//将符合要求的参数添加到集合中
list_first.add(index_first);
list_end.add(index_end);
i++;
index_end--;
index_first++;
//继续遍历
continue;
}else if (temp > target){
index_end--;
}else {
index_first++;
}
}
//输出结果
for (j=0;j<list_first.size();j++){
System.out.println("第"+ (j+1) +"组:");
System.out.println(list_first.get(j) +" * "+ list_first.get(j)
+" + "+ list_end.get(j)
+" * "+ list_end.get(j)
+" = " + target);
}
}
}