• 算法通关村第13关【白银】| 数字与数学高频问题


    数组实现加法

    1.加一

    思路:不进位末尾加一,进位挨个加一

    99,999...进位,新建长度+1的数组,res[0]=1,直接返回

    1. lass Solution {
    2. public int[] plusOne(int[] digits) {
    3. for(int i = digits.length-1;i>=0;i--){
    4. int num = ++digits[i];
    5. if(num<10){
    6. return digits;
    7. }else{
    8. digits[i] = num % 10;
    9. }
    10. }
    11. int[] res = new int[digits.length + 1];
    12. res[0] = 1;
    13. return res;
    14. }
    15. }

    2.字符串相加

    思路:从尾部加起,记录进位/10,本位%10,位数不一样0补齐

    1. class Solution {
    2. public String addStrings(String num1, String num2) {
    3. char[] s1 = num1.toCharArray();
    4. char[] s2 = num2.toCharArray();
    5. StringBuilder sb = new StringBuilder();
    6. int len1 = s1.length-1;
    7. int len2 = s2.length-1;
    8. int carry = 0;
    9. while(carry != 0 || len1>=0||len2>=0){
    10. int n1 = 0;
    11. int n2 = 0;
    12. if(len1>=0&&len2>=0){
    13. n1 = s1[len1] - '0';
    14. n2 = s2[len2] - '0';
    15. }
    16. else if(len2<0&&len1<0){
    17. n1 = 0;
    18. n2 = 0;
    19. }
    20. else if(len1<0){
    21. n2 = s2[len2] - '0';
    22. n1=0;
    23. }
    24. else if(len2<0){
    25. n1 = s1[len1] - '0';
    26. n2=0;
    27. }
    28. int num = n1+n2+carry;
    29. if(num>=10){
    30. sb.append(num%10);
    31. carry = num/10;
    32. }else{
    33. sb.append(num);
    34. carry = 0;
    35. }
    36. len1--;
    37. len2--;
    38. }
    39. return sb.reverse().toString();
    40. }
    41. }

    3.二进制加法

    思路:和十进制加法一样,逢二进一/2,本位取模%2,位数不一样0补齐

    1. class Solution {
    2. public String addBinary(String a, String b) {
    3. StringBuilder sb = new StringBuilder();
    4. int carry = 0;
    5. int len1 = a.length();
    6. int len2 = b.length();
    7. for(int i = len1 - 1,j = len2 - 1;(i>=0||j>=0||carry!=0);i--,j--){
    8. int n1 = i >= 0? a.charAt(i) - '0' : 0;
    9. int n2 = j >= 0? b.charAt(j) - '0' : 0;
    10. int n = n1 + n2 + carry;
    11. if(n>=2){
    12. sb.append(n%2);
    13. carry = n/2;
    14. }else{
    15. sb.append(n);
    16. carry = 0;
    17. }
    18. }
    19. return sb.reverse().toString();
    20. }
    21. }

    幂运算

    1.2的幂

    思路:每次除2直到除到底是不是能除尽,也就是2的n次方等于n。

    1. class Solution {
    2. public boolean isPowerOfTwo(int n) {
    3. if(n%2!=0&&n!=1||n==0){
    4. return false;
    5. }
    6. while(n%2==0){
    7. n = n >> 1;
    8. }
    9. if(n!=1){
    10. return false;
    11. }else{
    12. return true;
    13. }
    14. }
    15. }

    解法二:位运算,2的n次方说明首位为1其他位都是0,通过n&(n-1)将末尾1变0 比较是否为0 

    1. public static boolean isPowerOfTwo2(int n) {
    2. return n > 0 && (n & (n - 1)) == 0;
    3. }

    2.3的幂

    思路:同上一题,2变成3

    1. class Solution {
    2. public boolean isPowerOfThree(int n) {
    3. if(n%2==0||n<=0){
    4. return false;
    5. }
    6. while(n%3==0){
    7. n /= 3;
    8. }
    9. return n == 1;
    10. }
    11. }

    解法二:位运算,int范围内3的最高幂次数是3的19次方1162261467,只需要去除n能除整就是

    1. public static boolean isPowerOfThree2(int n) {
    2. return n > 0 && 1162261467 % n == 0;
    3. }

    3.4的幂

    1. class Solution {
    2. public boolean isPowerOfFour(int n) {
    3. if(n == 1){
    4. return true;
    5. }
    6. if(n%2!=0||n<=0){
    7. return false;
    8. }
    9. while(n%4 == 0){
    10. n /= 4;
    11. }
    12. return n == 1;
    13. }
    14. }

    解法二:位运算,4(2^2)的n次方说明首位为1其他位都是0,同时它还是2的n次方,特别的首位1处在奇数位置上,例如:100、10000,通过n&(n-1)将末尾1变0 比较是否首位为1其他位为0,再然后判断1是不是在奇数位置上,也就是&偶数位全是1奇数为全是0,如果偶数位为1就false

    1. class Solution {
    2. public boolean isPowerOfFour(int n) {
    3. return n > 0 && (n & (n - 1)) == 0 && (n & 0xaaaaaaaa) == 0;
    4. }
    5. }

    4.幂函数

    思路:快速幂,折半乘

    快速幂+递归,遇到奇数*x

    1. class Solution {
    2. public double myPow(double x, int n) {
    3. if(x==1||n==0){
    4. return 1.0;
    5. }
    6. if(x == 0){
    7. return 0.0;
    8. }
    9. long N = n;
    10. return n>0 ? quickMul(x,N) : 1.0/quickMul(x,-N);
    11. }
    12. public double quickMul(double x,long n){
    13. if(n == 0){
    14. return 1.0;
    15. }
    16. double res = quickMul(x,n/2);
    17. if(n%2==1){
    18. return res*res*x;
    19. }else{
    20. return res*res;
    21. }
    22. }
    23. }

    快速幂+迭代

    13的二进制为1101,15的二进制为1111

    3^13=3^8*3^4*3^0*3^1

    再如3^15 = 3^8*3^4*3^2*3^1

    进行幂次方拆分,从低位1开始每循环右移一次就x平方一次,遇见1结果就*x

    1. class Solution {
    2. public double myPow(double x, int n) {
    3. if(x==1||n==0){
    4. return 1.0;
    5. }
    6. if(x == 0){
    7. return 0.0;
    8. }
    9. long N = n;
    10. if(n<0){
    11. N = -N;
    12. }
    13. double res = 1.0;
    14. while(N>0){
    15. if((N & 1) == 1){
    16. res = res*x;
    17. }
    18. x *= x;
    19. N = N/2;
    20. }
    21. return n<0 ? 1.0/res : res;
    22. }
    23. }

  • 相关阅读:
    Linux小程序-进度条
    04、关联关系映射
    2023年建筑电工(建筑特殊工种)证考试题库及建筑电工(建筑特殊工种)试题解析
    隐私计算python实现Paillier同态加密
    php+vue+Elementui大学生心理健康测评网站
    JavaWeb-JSP+Servlet+Mysql实现JavaWeb基础项目
    什么是Docker容器?Docker容器和VM有什么区别?
    ps怎么把图片变清晰,自学ps软件photoshop2022,简单快速用ps让照片更清晰更有质感
    【牛客网】OR59 字符串中找出连续最长的数字串
    ChatGPT使用技巧整理
  • 原文地址:https://blog.csdn.net/Candy___i/article/details/132846890