数的奥秘之幂数与完全平方数

举报
未见花闻 发表于 2022/04/30 00:34:25 2022/04/30
【摘要】 数的奥秘之幂数与完全平方数

⭐️前面的话⭐️

大家好!本篇文章将以力扣平台3道关于幂数和1道关于完全平方数的题为背景,探索幂数与完全平方数的内心世界,展示代码语言暂时为:Java,C/C++。

📒博客主页:未见花闻的博客主页
🎉欢迎关注🔎点赞👍收藏⭐️留言📝
📌本文由未见花闻原创!
📆华为云首发时间:🌴2022年4月30日🌴
✉️坚持和努力一定能换来诗与远方!
💭参考书籍:📚《C语言程序设计》📚《剑指offer》
💬参考在线编程网站:🌐牛客网🌐力扣
博主的码云gitee,平常博主写的程序代码都在里面。
博主的github,平常博主写的程序代码都在里面。
🍭作者水平很有限,如果发现错误,一定要及时告知作者哦!感谢感谢!


⛄️Part1.幂数⛄️

⭐️2 的幂⭐️

🔐题目详情

给你一个整数 n,请你判断该整数是否是 2 的幂次方。如果是,返回 true ;否则,返回 false 。
如果存在一个整数 x 使得 n = 2 x n = 2^x ,则认为 n 是 2 的幂次方。

示例:

输入:n = 1
输出:true
解释:20 = 1
输入:n = 16
输出:true
解释:24 = 16
输入:n = 3
输出:false

提示:
n n 的范围为整型 i n t int 的范围。

来源:力扣(LeetCode)链接:2 的幂

💡解题思路

利用 2 2 的幂的二进制序列中只有一个1并且大于0的性质,将此题转换为求二进制中1的个数,如果为1个,则该数为 2 2 的幂。
二进制1的个数求法:
参考历史博文:
剑指offer系列——剑指 Offer 15. 二进制中1的个数(C语言)

方法1: 以C语言为例,整型的储存形式是32位二进制序列,内存中储存的补码,对于正整数,二进制原码补码相同,对于负整数,补码是在原码除最高位取反得到反码的基础上加1。
最先想到的就是对输入的整数的二进制序列每一位进行判断是否是1。我们可以将这个二进制序列与1进行按位与运算,由于1的二进制序列只有末位是1,所以如果这个二进制序列的末位为1则返回1,否则返回0。然后我们再对这个二进制序列进行右移位操作,这样就能舍弃最右边的一个序列,经过32次操作,就能判断整个二进制序列有多少个1

方法2: 假设输入的整数为n,我们不妨将nn-1进行按位与运算,然后你会发现运算的结果与n相比,二进制序列中少了一个1,通俗来说,每进行一次这样的运算,二进制中的1就会减少一个,我们可以根据这种运算的特点来设计解法。我们可以将每次n&(n-1)的结果保存给n,直到n=0。计算进行运算的次数,即1的个数。

上面两种方法都可以求二进制序列中1的位数,本文采取方法2

❓为什么 2 的幂 2的幂 的二进制序列只有一个1

不妨设一个数的二进制序列为,其中 a , b , c , d a,b,c,d 01

a b c d abcd

则所对应十进制数 x   =   d × 2 0 + c × 2 1 + b × 2 2 + a × 2 3 x\ =\ d×2^0+c×2^1+b×2^2+a×2^3
如果一个数为 2 2 的幂,则 a , b , c , d a,b,c,d 中有且只有一个数为 1 1 其他均为 0 0
推广一下,对于32位,64位二进制也是如此。

🔑源代码

Java

//具体写
class Solution {
    public boolean isPowerOfTwo(int n) {
        int count = 0;
        if (n < 0){
            return false;
        }
        while (n != 0){
            n &= n - 1;
            count++;
        }
        if(count == 1){
            return true;
        }
        else{
            return false;
        }
    }
}
//简略写
class Solution {
    public boolean isPowerOfTwo(int n) {
        return n > 0 && ((n & (n - 1)) == 0);
    }
}

C

bool isPowerOfTwo(int n){
    return n > 0 && ((n & (n - 1)) == 0);
}

C++

class Solution {
public:
    bool isPowerOfTwo(int n) {
        return n > 0 && ((n & (n - 1)) == 0);
    }
};

⭐️3 的幂⭐️

🔐题目详情

给定一个整数,写一个函数来判断它是否是 3 的幂次方。如果是,返回 true ;否则,返回 false 。
整数 n 是 3 的幂次方需满足:存在整数 x 使得 n = 3 x n = 3^x

示例:

输入:n = 27
输出:true
输入:n = 45
输出:false

提示:
n n 的范围为整型 i n t int 的范围。

来源:力扣(LeetCode)链接:3 的幂

💡解题思路

如果一个数是3的幂,那么这个数一直除3,第一次不能被除尽时,被除数一定为1。比如9,9/3=3,3/3=1,1不能被3除尽,此时被除数为1。如果一个数不是3的幂一直除3第一次不能除尽的被除数一定不是1
换个说法,3的幂由因子31组成,所以不断除以3,最后得到的数一定是另一个因子1

🔑源代码

Java

class Solution {
    public boolean isPowerOfThree(int n) {
        if (n <= 0) {
            return false;
        }
        int m = n;
        while (m % 3 == 0) {
            m /= 3;
        }
        if (m == 1) {
            return true;
        }
        else {
            return false;
        }
    }
}

C

bool isPowerOfThree(int n){
    if (n <= 0) 
    {
        return 0;
    }
    int m = n;
    while(m % 3 == 0)
    {
        m /= 3;
    }
    if (m == 1) 
    {
        return true;
    }
    return false;
}

C++

class Solution {
public:
    bool isPowerOfThree(int n) {
        if (n <= 0) 
        {
            return 0;
        }
        int m = n;
        while(m % 3 == 0)
        {
            m /= 3;
        }
        if (m == 1) 
        {
            return true;
        }
        return false;
    }
};

⭐️4 的幂⭐️

🔐题目详情

给定一个整数,写一个函数来判断它是否是 4 的幂次方。如果是,返回 true ;否则,返回 false 。
整数 n 是 4 的幂次方需满足:存在整数 x 使得 n = 4 x n = 4^x

示例:

输入:n = 16
输出:true
输入:n = 5
输出:false

提示:
n n 的范围为整型 i n t int 的范围。

来源:力扣(LeetCode)链接:4 的幂

💡解题思路

一个大于0的数,该数的二进制只有一位是1且该数模3的结果为1,则该数为4的幂。

🔎推导:
由二项式定理:

4 x = ( 3 + 1 ) x = k 0 × 3 x × 1 0 + k 1 × 3 x 1 × 1 1 + . . . + k x × 3 0 × 1 x 4^x = (3 + 1)^x = k_0×3^x×1^0 + k_1×3^{x-1}×1^1 + ... + k_x×3^0×1^x

其中最末项系数 k x   = C x x = 1 k_x~ =C_{x}^{x} = 1 ,所以 4 x   %   3 = 1 4^x\ \%\ 3 = 1

4的幂一定也是2的幂,所以它的二进制中与2的幂一样只有一个1,一个数是2的幂但不是4的幂,同由二项式定理,该数模3结果一定是2:

y = 2 x = ( 3 1 ) x = k 0 × 3 x × ( 1 ) 0 + k 1 × 3 x 1 × ( 1 ) 1 + . . . + k x × 3 0 × ( 1 ) x y=2^x = (3 - 1)^x = k_0×3^x×(-1)^0 + k_1×3^{x-1}×(-1)^1 + ... + k_x×3^0×(-1)^x

其中最末项系数 k x   = C x x = 1 k_x~ =C_{x}^{x} = 1
x为偶数时,该数既是2的幂也是4的幂,此时 ( 1 ) x = 1 (-1)^x=1

原式 = k 0 × 3 x × ( 1 ) 0 + k 1 × 3 x 1 × ( 1 ) 1 + . . . + 1 原式=k_0×3^x×(-1)^0 + k_1×3^{x-1}×(-1)^1 + ... + 1

得到 y % 3 = 1 y\%3=1
x为奇数时,该数是2的幂但不是4的幂,此时 ( 1 ) x = 1 (-1)^x=-1

原式 = k 0 × 3 x × ( 1 ) 0 + k 1 × 3 x 1 × ( 1 ) 1 + . . . 1 = k 0 × 3 x × ( 1 ) 0 + k 1 × 3 x 1 × ( 1 ) 1 + . . . 3 + 2 原式=k_0×3^x×(-1)^0 + k_1×3^{x-1}×(-1)^1 + ... - 1=k_0×3^x×(-1)^0 + k_1×3^{x-1}×(-1)^1 + ... - 3 + 2

得到 y % 3 = 2 y\%3=2
再加上4的幂和2的幂一样,二进制序列中只有一个1,所以可以得出结论:

一个大于 0 的数,该数的二进制只有一位是 1 且该数模 3 的结果为 1 ,则该数为 4 的幂。 一个大于0的数,该数的二进制只有一位是1且该数模3的结果为1,则该数为4的幂。

🔑源代码

Java

class Solution {
    public boolean isPowerOfFour(int n) {
        return n > 0 && ((n &(n-1)) == 0) && n % 3 == 1;
    }
}

C

bool isPowerOfFour(int n){
    return n > 0 && ((n &(n-1)) == 0) && n % 3 == 1;
}

C++

class Solution {
public:
    bool isPowerOfFour(int n) {
        return n > 0 && ((n &(n-1)) == 0) && n % 3 == 1;
    }
};

⛄️Part2.完全平方数⛄️

⭐️完全平方数⭐️

🔐题目详情

给定一个 正整数 num ,编写一个函数,如果 num 是一个完全平方数,则返回 true ,否则返回 false 。
进阶:不要 使用任何内置的库函数,如 sqrt 。

示例:

输入:num = 16
输出:true
输入:num = 14
输出:false

提示:
1 < = n u m < = 2 31 1 1 <= num <= 2^{31} - 1

来源:力扣(LeetCode)链接:完全平方数

💡解题思路

方法1:暴力遍历,注意溢出,不推荐。
方法2: 利用 1 + 3 + 5 + 7 + 9 + + ( 2 n 1 ) = n 2 1+3+5+7+9+…+(2n-1)=n^2 公式计算。
方法3:二分查找,具体看代码。

🔑源代码

方法1:Java

class Solution {
    public boolean isPerfectSquare(int num) {
        for (int i = 1; (long)(i * i) <= (long)num && i <= num / 2 + 1; i++) {
            if (i * i == num) {
                return true;
            }
        }
        return false;
    }
}

方法2:C

bool isPerfectSquare(int num){
    int i = 1;
    long sum = 0;
    while (sum <= num) {
        if (sum == num) {
            return true;
        }
        sum += i;
        i += 2;
    }
    return false;
}

方法3:Java

class Solution {
    public boolean isPerfectSquare(int num) {
        int left = 1;
        int right = num;
        while (left <= right) {
            int mid = left + (right - left) / 2;
            int div = num / mid;
            if (mid == div) {
                if (mid * div == num) {
                    return true;
                }
                left = mid + 1;
            }else if (mid > div) {
                right = mid - 1;
            }else {
                left = mid + 1;
            }
        }
        return false;
    }
}

🌱总结🌱

  1. 2 2 的幂的二进制序列中只有一个1并且大于0
  2. 3 3 的幂由因子31组成,所以不断除以3,最后得到的数一定是另一个因子1
  3. 一个大于0的数,该数的二进制只有一位是1且该数模3的结果为1,则该数为 4 4 的幂。
  4. 计算完全平方数公式: 1 + 3 + 5 + 7 + 9 + + ( 2 n 1 ) = n 2 1+3+5+7+9+…+(2n-1)=n^2
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。