• 力扣刷题篇之数与位1


    系列文章目录


    目录

    系列文章目录

    前言

    一、进制转换

     

    总结


    前言

    本系列是个人力扣刷题汇总,本文是数与位。刷题顺序按照[力扣刷题攻略] Re:从零开始的力扣刷题生活 - 力扣(LeetCode)


    一、进制转换

    67. 二进制求和 - 力扣(LeetCode)

    主要思路是从二进制串的最低位(右边)开始,逐位相加,使用 carry 变量来处理进位。在遍历的过程中,分别处理相等和不相等的情况,并更新结果数组。最后,检查最高位是否有进位,若有,则在结果数组的最前面加上进位。最终返回相加的结果。

    注意,在Java中,如果你创建一个字符串数组但还没有为元素分配具体的值,那么数组的元素将被初始化为 null

    1. class Solution {
    2. public static String addBinary(String a, String b) {
    3. // 保持a的长度大于等于b的长度,方便处理
    4. if (a.length() < b.length()) {
    5. return addBinary(b, a);
    6. }
    7. // 创建一个字符数组来保存相加的结果,长度为a.length() + 1
    8. char[] sum = new char[a.length() + 1];
    9. int indexA = a.length() - 1, diffLen = a.length() - b.length();
    10. char carry = '0'; // 进位初始为0
    11. // 从右往左遍历a的每一位
    12. while (indexA > -1) {
    13. // 获取b的相应位,如果b的长度小于a,超出部分视为0
    14. char bitB = indexA - diffLen > -1 ? b.charAt(indexA - diffLen) : '0';
    15. // 判断当前位与进位的情况,更新相应位置的值和进位
    16. if (a.charAt(indexA) == bitB) {
    17. sum[indexA-- + 1] = carry;
    18. carry = bitB;
    19. } else {
    20. sum[indexA-- + 1] = carry == '0' ? '1' : '0';
    21. }
    22. }
    23. // 处理最高位的进位
    24. sum[0] = carry;
    25. // 返回相加的结果,去掉可能多余的前导零
    26. return carry == '1' ? new String(sum, 0, a.length() + 1) : new String(sum, 1, a.length());
    27. }
    28. }

     504. 七进制数 - 力扣(LeetCode)

    把十进制变成七进制:

    这个我想得太繁琐了 

    1. class Solution {
    2. public String convertToBase7(int num) {
    3. // 如果数字的绝对值小于7,直接返回数字的字符串表示
    4. if (Math.abs(num) < 7) {
    5. return Integer.toString(num);
    6. }
    7. // 判断数字的正负性
    8. boolean isPos = true;
    9. if (num < 0) {
    10. isPos = false;
    11. }
    12. num = Math.abs(num);
    13. // 计算数字的位数
    14. int temp = num;
    15. int count = 0;
    16. while (temp / 7 > 0) {
    17. count++;
    18. temp /= 7;
    19. }
    20. // 创建数组来存储7进制的每一位数字
    21. int[] res = new int[count + 1];
    22. for (int i = count; i >= 0; i--) {
    23. // 计算并存储当前位的数字
    24. res[count - i] = num / (int) Math.pow(7, i);
    25. num = num - (num / (int) Math.pow(7, i)) * (int) Math.pow(7, i);
    26. }
    27. // 使用StringBuilder拼接数组中的数字
    28. StringBuilder result = new StringBuilder();
    29. for (int digit : res) {
    30. result.append(digit);
    31. }
    32. // 返回结果,如果原始数字为负数,则加上负号
    33. return isPos ? result.toString() : "-" + result.toString();
    34. }
    35. }

    不如,取余的,不断更新num,然后翻转

    1. class Solution {
    2. public String convertToBase7(int num) {
    3. if(num == 0) return "0";
    4. boolean isN = num < 0;
    5. if(isN) {
    6. num = -num;
    7. }
    8. StringBuilder sb = new StringBuilder();
    9. while(num > 0) {
    10. sb.append(num % 7);
    11. num /= 7;
    12. }
    13. if(isN) {
    14. sb.append("-");
    15. }
    16. return sb.reverse().toString();
    17. }
    18. }

      

    当然,也可以,抽象的哈哈哈哈(一个简单题越搞越多)

    Java内置的 Integer.toString(int i, int radix) 方法,它可以将整数 i 转换为指定基数(radix)的字符串表示。在这里,基数是7,所以它直接实现了将整数转换为7进制字符串的功能。这是一种更简洁的实现方式,避免了手动计算每一位数字和使用循环的繁琐过程。

    1. class Solution {
    2. public String convertToBase7(int num) {
    3. return Integer.toString(num, 7);
    4. }
    5. }

    405. 数字转换为十六进制数 - 力扣(LeetCode)

    经过上一题启示,先用秀的方法

    Java 内置的 Integer.toHexString(int num) 方法,该方法用于将整数转换为十六进制字符串。

    1. class Solution {
    2. public String toHex(int num) {
    3. return Integer.toHexString(num);
    4. }
    5. }

     

     

     使用了位运算和循环,从高位到低位依次取出每个四位二进制数的值,然后将其转换为对应的十六进制字符。最终,将这些字符拼接起来形成最终的十六进制字符串。

    这个位运算很有意思:

    1. class Solution {
    2. public String toHex(int num) {
    3. // 如果 num 为 0,直接返回 "0"
    4. if (num == 0) {
    5. return "0";
    6. }
    7. // 用于拼接十六进制字符串的 StringBuffer
    8. StringBuffer sb = new StringBuffer();
    9. // 从高位到低位遍历每个四位二进制数
    10. for (int i = 7; i >= 0; i--) {
    11. // 取出当前四位二进制数的值
    12. int val = (num >> (4 * i)) & 0xf;
    13. // 如果 StringBuffer 非空或者当前值大于 0,则将当前值添加到 StringBuffer 中
    14. if (sb.length() > 0 || val > 0) {
    15. // 将数字转换为十六进制字符
    16. char digit = val < 10 ? (char) ('0' + val) : (char) ('a' + val - 10);
    17. sb.append(digit);
    18. }
    19. }
    20. // 返回最终的十六进制字符串
    21. return sb.toString();
    22. }
    23. }

    妙:先将 temp 不断右移,直到变为 0,这样可以得到与 num 二进制表示相同位数的全1的数。然后通过异或操作,将 num 的每一位取反,得到最终的补数。

    1. class Solution {
    2. public int findComplement(int num) {
    3. // 将 temp 初始化为 num,c 初始化为 0
    4. int temp = num, c = 0;
    5. // 循环右移 temp,直到 temp 变为 0
    6. while (temp > 0) {
    7. temp >>= 1; // 右移一位
    8. c = (c << 1) + 1; // 将 c 左移一位,并将最低位设置为 1
    9. }
    10. // 返回 num 与 c 的异或结果,即 num 的补数
    11. return num ^ c;
    12. }
    13. }

    通过迭代找到 num 的最高位的位置,然后构造一个掩码 mask,用于取反高位以下的所有位。最后,通过异或操作得到 num 的补数。这种方法避免了使用循环右移的方式,采用了更直接的方法。

    其实这两种方法都是找异或的掩码,方法也差不多。

    1. class Solution {
    2. public int findComplement(int num) {
    3. // 初始化 highbit 为 0
    4. int highbit = 0;
    5. // 遍历 1 到 30,找到 num 的最高位的位置
    6. for (int i = 1; i <= 30; ++i) {
    7. if (num >= 1 << i) {
    8. highbit = i;
    9. } else {
    10. break;
    11. }
    12. }
    13. // 构造一个掩码 mask,用于取反高位以下的所有位
    14. int mask = highbit == 30 ? 0x7fffffff : (1 << (highbit + 1)) - 1;
    15. // 返回 num 与 mask 的异或结果,即 num 的补数
    16. return num ^ mask;
    17. }
    18. }

     66. 加一 - 力扣(LeetCode)

     要处理一个特别的情况,全是九的时候,这里处理得很妙。

    1. class Solution {
    2. public int[] plusOne(int[] digits) {
    3. for (int i = digits.length - 1; i >= 0; i--) {
    4. if (digits[i] != 9) {
    5. digits[i]++;
    6. return digits;
    7. }
    8. digits[i] = 0;
    9. }
    10. //跳出for循环,说明数字全部是9
    11. int[] temp = new int[digits.length + 1];
    12. temp[0] = 1;
    13. return temp;
    14. }
    15. }

     开摆的节奏哈哈哈

    1. class Solution {
    2. public int largestPalindrome(int n) {
    3. switch (n) {
    4. case 1: return 9;
    5. case 2: return 987;
    6. case 3: return 123;
    7. case 4: return 597;
    8. case 5: return 677;
    9. case 6: return 1218;
    10. case 7: return 877;
    11. default: return 475;
    12. }
    13. }
    14. }

    枚举回文数的左半部分,然后构造右半部分,查找是否存在两个 n 位数的乘积,得到最大回文数。该方法在处理较小的 n 时效率较高,但可能对于较大的 n 不够高效。

    1. class Solution {
    2. public int largestPalindrome(int n) {
    3. // 对于 n = 1,最大回文数为 9
    4. if (n == 1) {
    5. return 9;
    6. }
    7. // 计算 n 位数的上限值
    8. int upper = (int) Math.pow(10, n) - 1;
    9. int ans = 0;
    10. // 枚举回文数的左半部分
    11. for (int left = upper; ans == 0; --left) {
    12. long p = left;
    13. // 翻转左半部分到其自身末尾,构造回文数 p
    14. for (int x = left; x > 0; x /= 10) {
    15. p = p * 10 + x % 10;
    16. }
    17. // 枚举右半部分,查找是否存在两个 n 位数的乘积
    18. for (long x = upper; x * x >= p; --x) {
    19. if (p % x == 0) { // x 是 p 的因子
    20. ans = (int) (p % 1337);
    21. break;
    22. }
    23. }
    24. }
    25. return ans;
    26. }
    27. }

    564. 寻找最近的回文数 - 力扣(LeetCode)

    1. class Solution {
    2. public String nearestPalindromic(String n) {
    3. Long input = Long.parseLong(n);
    4. int order = (int)Math.pow(10, n.length()/2);
    5. Long noChange = mirror(input);
    6. Long larger = mirror((input/order)*order + order + 1);
    7. Long smaller = mirror((input/order)*order - 1);
    8. if(noChange > input){
    9. larger = noChange < larger ? noChange : larger;
    10. }
    11. else if(noChange < input){
    12. smaller = noChange > smaller ? noChange : smaller;
    13. }
    14. return (input - smaller) <= (larger - input) ? String.valueOf(smaller) : String.valueOf(larger);
    15. }
    16. Long mirror(Long ans) {
    17. char[] arr = String.valueOf(ans).toCharArray();
    18. int i = 0;
    19. int j = arr.length-1;
    20. while(i < j){
    21. arr[j--] = arr[i++];
    22. }
    23. return Long.parseLong(String.valueOf(arr));
    24. }
    25. }

    1. class Solution {
    2. public int reverse(int x) {
    3. // int len=0,y=0,result=0,sub=1;
    4. // if(x<0) sub=-1;
    5. // x=Math.abs(x);
    6. // while(x>0){
    7. // y=x%10;
    8. // x=x/10;
    9. // if(x>0){
    10. // result=10*(y+result);
    11. // }else{
    12. // result=result+y;
    13. // }
    14. // }
    15. // //return sub*result>2^(31)-1 || sub*result<-2^(31) ? 0 : sub*result;
    16. // return sub * result > Math.pow(2, 31) - 1 || sub * result < -Math.pow(2, 31) ? 0 : sub * result;
    17. // long n = 0;
    18. // while(x != 0) {
    19. // n = n*10 + x%10;
    20. // x = x/10;
    21. // }
    22. // return (int)n==n? (int)n:0;
    23. int result = 0;
    24. while (x != 0) {
    25. //每次取末尾数字
    26. int temp = x % 10;
    27. //判断是否 大于 最大32位整数
    28. /* if (result > 214748364 || (result == 214748364 && temp > 7)) {
    29. return 0;
    30. }
    31. //判断是否 小于 最小32位整数
    32. if (result < -214748364 || (result == -214748364 && temp < -8)) {
    33. return 0;
    34. }*/
    35. /* 因为x本身会被int限制,
    36. 当x为正数并且位数和Integer.MAX_VALUE的位数相等时首位最大只能为2,
    37. 所以逆转后不会出现res = Integer.MAX_VALUE / 10 && tmp > 2的情况,
    38. 自然也不需要判断res==214748364 && tmp>7了,反之负数情况也一样*/
    39. if (result > Integer.MAX_VALUE / 10 || result < Integer.MIN_VALUE / 10) {
    40. return 0;
    41. }
    42. result = result * 10 + temp;
    43. x /= 10;
    44. }
    45. return result;
    46. }
    47. }


    总结

    今天把数与位的第一个部分,进制转换做完了,感觉大部分都是简单题,仔细想想也能自己敲出来,需要注意的是一些回文数和进制的处理需要牢记。多敲!

  • 相关阅读:
    Prometheus PromQL及传统部署 Alertmanager 发送告警
    k8s的服务Service暴露应用
    elk下载地址
    YOLO系列 --- YOLOV7算法(六):YOLO V7算法onnx模型部署
    有效的网络带宽监控策略
    Splunk 之 filed 恢复
    一文读懂什么是布隆过滤器
    c 取字符串中的子串
    算法金 | 统计学的回归和机器学习中的回归有什么差别?
    Java-基于SSM的学生综合考评管理系统
  • 原文地址:https://blog.csdn.net/m0_66076989/article/details/134424721