java数据结构与算法刷题-----LeetCode633. 平方数之和

java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.csdn.net/grd_java/article/details/123063846

java数据结构与算法刷题-----LeetCode633. 平方数之和_第1张图片

思路一:双指针

可以使用双指针,不断从两个方向匹配值。而两个数的平方和不能大于c。所以范围只需限制在[0, c \sqrt[]{c} c ], 注意:两个整数可以相等
java数据结构与算法刷题-----LeetCode633. 平方数之和_第2张图片

class Solution {
    //时间复杂度O(根号c),空间复杂度O(1)
    public boolean judgeSquareSum(int c) {
        //双指针,因为任何数表示成两个比自己小的数的平方和时
        //都不可能大于自己的平方根,故,只需要从0到sqrt(c)即可
        //例如c=25, 5*5就已经25了,不可能有到6的情况,因为6*6=35已经比c大了
        long left = 0, right = (long)Math.sqrt(c);//long类型避免溢出
        while(left<=right){//左右指针,指向同一个值时,结束查找,表示没找着
            long sum = left*left + right*right;
            if(sum==c) return true;//如果找到返回true
            else if (sum>c) right--;//如果值太大,右边缩小
            else left++;//值太小,左边扩大
        }
        return false;//没找着返回false;
    }
}

思路二:费马平方和定理: 对于形如 p=4k+1 的素数 p,存在整数 x 和 y,使得 p = x 2 + y 2 p = x^2 + y^2 p=x2+y2 其中 x 和 y 是整数.

  1. 加粗样式
    java数据结构与算法刷题-----LeetCode633. 平方数之和_第3张图片
class Solution {
    public boolean judgeSquareSum(int c) {
        for (int base = 2; base * base <= c; base++) {
            // 如果不是因子,枚举下一个
            if (c % base != 0) {
                continue;
            }

            // 计算 base 的幂
            int exp = 0;
            while (c % base == 0) {
                c /= base;
                exp++;
            }

            // 根据 Sum of two squares theorem 验证
            if (base % 4 == 3 && exp % 2 != 0) {
                return false;
            }
        }

      	// 例如 11 这样的用例,由于上面的 for 循环里 base * base <= c ,base == 11 的时候不会进入循环体
      	// 因此在退出循环以后需要再做一次判断
        return c % 4 != 3;
    }
}

刷题一定要坚持,总结套路,不单单要把题做出来,要举一反三,也要参考别人的思路,学习别人解题的优点,找出你觉得可以优化的点。

  1. 单链表解题思路:双指针、快慢指针、反转链表、预先指针
  1. 双指针:对于单链表而言,可以方便的让我们遍历结点,并做一些额外的事
  2. 快慢指针:常用于找链表中点,找循环链表的循环点,一般快指针每次移动两个结点,慢指针每次移动一个结点。
  3. 反转链表:通常有些题,将链表反转后会更好做,一般选用三指针迭代法,递归的空间复杂度有点高
  4. 预先指针:常用于找结点,比如找倒数第3个结点,那么定义两个指针,第一个指针先移动3个结点,然后两个指针一起遍历,当第一个指针遍历完成,第二个指针指向的结点就是要找的结点
  1. 数组解题思路:双指针、三指针,下标标记
  1. 双指针:多用于减少时间复杂度,快速遍历数组
  2. 三指针:多用于二分查找,分为中间指针,左和右指针
  3. 下标标记:常用于在数组范围内找东西,而不想使用额外的空间的情况,比如找数组长度为n,元素取值范围为[1,n]的数组中没有出现的数字,遍历每个元素,然后将对应下标位置的元素变为负数或者超出[1,n]范围的正数,最后没有发生变化的元素,就是缺少的值。

你可能感兴趣的:(算法,java,数据结构,leetcode,算法)