进制转换(一) - 入门

简介: 进制转换(一) - 入门

一、概念

x进制转y进制负数补码问题

二、模板

看例题

三、例题

题:剑指 Offer 15. 二进制中1的个数

编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 '1' 的个数(也被称为 汉明重量).)。

提示:

  • 请注意,在某些语言(如 Java)中,没有无符号整数类型。在这种情况下,输入和输出都将被指定为有符号整数类型,并且不应影响您的实现,因为无论整数是有符号的还是无符号的,其内部的二进制表示形式都是相同的。
  • 在 Java 中,编译器使用 二进制补码 记法来表示有符号整数。因此,在上面的 示例 3 中,输入表示有符号整数 -3。

示例 1:

输入:n = 11 (控制台输入 00000000000000000000000000001011)
输出:3
解释:输入的二进制串 00000000000000000000000000001011 中,共有三位为 '1'。

示例 2:

输入:n = 128 (控制台输入 00000000000000000000000010000000)
输出:1
解释:输入的二进制串 00000000000000000000000010000000 中,共有一位为 '1'。

示例 3:

输入:n = 4294967293 (控制台输入 11111111111111111111111111111101,部分语言中 n = -3)
输出:31
解释:输入的二进制串 11111111111111111111111111111101 中,共有 31 位为 '1'。

提示:

输入必须是长度为 32 的 二进制串 。

解:

解题思路:位运算

移位判断

AC代码:

public class Solution {
    // you need to treat n as an unsigned value
    public int hammingWeight(int n) {
        int res = 0;
        while(n != 0) { // n可能正负
            res += n & 1;
            n >>>= 1;
        }
        return res;
    }
}

解题思路:位运算

巧用 n & n - 1

AC代码:

public class Solution {
    // you need to treat n as an unsigned value
    public int hammingWeight(int n) {
        int res = 0;
        while(n != 0) { 
            res ++;
            n &= n - 1;
        }
        return res;
    }
}

题:258. 各位相加

给定一个非负整数 num,反复将各个位上的数字相加,直到结果为一位数。返回这个结果。

示例 1:

输入: num = 38
输出: 2 
解释: 各位相加的过程为:
38 --> 3 + 8 --> 11
11 --> 1 + 1 --> 2
由于 2 是一位数,所以返回 2。

示例 1:

输入: num = 0
输出: 0

提示:

0 <= num <= 231 - 1
  • 进阶:你可以不使用循环或者递归,在 O(1) 时间复杂度内解决这个问题吗?

解:

解题思路:迭代

AC代码:

class Solution {
    public int addDigits(int num) {
        while(num >= 10) {
            int x = 0;
            while(num != 0) {
                x += num % 10;
                num /= 10;
            }
            num = x;
        }
        return num;
    }
}

解题思路:数学

科普:

在数学中,数根(又称位数根或数字根Digital root)是自然数的一种性质,换句话说,每个自然数都有一个数根。

数根是将一正整数的各个位数相加(即横向相加),若加完后的值大于10的话,则继续将各位数进行横向相加直到其值小于十为止[1],或是,将一数字重复做数字和,直到其值小于十为止,则所得的值为该数的数根。

例如54817的数根为7,因为5+4+8+1+7=25,25大于10则再加一次,2+5=7,7小于十,则7为54817的数根。

AC代码:

class Solution {
    public int addDigits(int num) {
        return (num - 1) % 9 + 1;
    }
}

题:1290. 二进制链表转整数

给你一个单链表的引用结点 head。链表中每个结点的值不是 0 就是 1。已知此链表是一个整数数字的二进制表示形式。

请你返回该链表所表示数字的 十进制值 。

示例 1:

输入:head = [1,0,1]
输出:5
解释:二进制数 (101) 转化为十进制数 (5)

示例 2:

输入:head = [0]
输出:0

示例 3:

输入:head = [1]
输出:1

示例 4:

输入:head = [1,0,0,1,0,0,1,1,1,0,0,0,0,0,0]
输出:18880

示例 5:

输入:head = [0,0]
输出:0

提示:

链表不为空。
链表的结点总数不超过 30。
每个结点的值不是 0 就是 1。

解:

解题思路:模拟

AC代码:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public int getDecimalValue(ListNode head) {
        int ans = 0;
        while(head != null) {
            ans = ans * 2 + head.val;
            head = head.next;
        }
        return ans;
    }
}

题:1837. K 进制表示下的各位数字总和

给你一个整数 n(10 进制)和一个基数 k ,请你将 n 从 10 进制表示转换为 k 进制表示,计算并返回转换后各位数字的 总和

转换后,各位数字应当视作是 10 进制数字,且它们的总和也应当按 10 进制表示返回。

示例 1:

输入:n = 34, k = 6
输出:9
解释:34 (10 进制) 在 6 进制下表示为 54 。5 + 4 = 9 。

示例 2:

输入:n = 10, k = 10
输出:1
解释:n 本身就是 10 进制。 1 + 0 = 1 。

提示:

1 <= n <= 100
2 <= k <= 10

解:

解题思路:模拟

AC代码:

class Solution {
    public int sumBase(int n, int k) {
        int x = 0;
        while(n != 0) {
            x += n % k;
            n /= k;
        }
        return x;
    }
}

题:1399. 统计最大组的数目

给你一个整数 n 。请你先求出从 1 到 n 的每个整数 10 进制表示下的数位和(每一位上的数字相加),然后把数位和相等的数字放到同一个组中。

请你统计每个组中的数字数目,并返回数字数目并列最多的组有多少个。

示例 1:

输入:n = 13
输出:4
解释:总共有 9 个组,将 1 到 13 按数位求和后这些组分别是:
[1,10],[2,11],[3,12],[4,13],[5],[6],[7],[8],[9]。总共有 4 个组拥有的数字并列最多。

示例 2:

输入:n = 2
输出:2
解释:总共有 2 个大小为 1 的组 [1],[2]。

示例 3:

输入:n = 15
输出:6

示例 4:

输入:n = 24
输出:5

提示:

1 <= n <= 10^4

解:

解题思路:哈希

AC代码:

class Solution {
    public int countLargestGroup(int n) {
        Map<Integer, Integer> map = new HashMap<>();
        int maxValue = 0;
        for(int i = 1; i <= n; ++ i) {
            int x = 0; 
            int num = i;
            while(num != 0) {
                x += num % 10;
                num /= 10;
            }
            map.put(x, map.getOrDefault(x, 0) + 1);
            maxValue = Math.max(maxValue, map.get(x));
        }
        int cnt = 0;
        for(Integer value : map.values()) {
            if(value == maxValue) cnt ++;
        }
        return cnt;
    }
}

题:504. 七进制数

给定一个整数 num,将其转化为 7 进制,并以字符串形式输出。

示例 1:

输入: num = 100
输出: "202"

示例 2:

输入: num = -7
输出: "-10"

提示:

-107 <= num <= 107

解:

解题思路:模拟

AC代码:

class Solution {
    public String convertToBase7(int num) {
        StringBuilder res = convert(Math.abs(num));
        if(num < 0) res.append("-");
        return res.reverse().toString();
    }
    StringBuilder convert(int num) {
        if(num == 0) return new StringBuilder("0");
        StringBuilder res = new StringBuilder();
        while(num != 0) {
            res.append(num % 7 + "");
            num /= 7;
        }
        return res;
    }
}

题:405. 数字转换为十六进制数

给定一个整数,编写一个算法将这个数转换为十六进制数。对于负整数,我们通常使用 补码运算 方法。

注意:

  1. 十六进制中所有字母(a-f)都必须是小写。
  2. 十六进制字符串中不能包含多余的前导零。如果要转化的数为0,那么以单个字符'0'来表示;对于其他情况,十六进制字符串中的第一个字符将不会是0字符。
  3. 给定的数确保在32位有符号整数范围内。
  4. 不能使用任何由库提供的将数字直接转换或格式化为十六进制的方法。

示例 1:

输入:
26

输出:
"1a"

示例 2:

输入:
-1

输出:
"ffffffff"

解:

解题思路:模拟

AC代码:

class Solution {
    public String toHex(int _num) {
        if(_num == 0) return "0";
        StringBuilder sb = new StringBuilder();
        long num = _num;
        if(num < 0) num = (long)(num + Math.pow(2, 32));
        while(num != 0) {
            long rem = num % 16;
            char c = (char)(rem + '0');
            if(rem >= 10) c = (char)(rem - 10 + 'a');
            sb.append(c);
            num /= 16;
        }
        return sb.reverse().toString();
    }
}

解题思路:位运算

将长度为32的二进制转化为16进制,本质是对其分组,4个为一组

AC代码:

class Solution {
    public String toHex(int num) {
        if(num == 0) return "0";
        StringBuilder sb = new StringBuilder();
        while(num != 0) {
            int x = num & 15;
            char c = (char)(x + '0');
            if(x >= 10) c = (char)(x - 10 + 'a');
            sb.append(c);
            num >>>= 4;
        }
        return sb.reverse().toString();
    }
}
相关文章
|
6月前
|
监控 安全 API
如何设计、维护和推广 API:专业人士的实用指南
API 在数字化环境中扮演着连接系统与应用的关键角色。设计卓越的 API 需明确目标、遵循 RESTful 原则、保持一致性和标准化。有效维护包括版本控制、性能监控、详细文档和负载优化。推广 API 通过内部培训、吸引开发者社区及展示成功案例。Apipost 提供全面工具集、无缝集成、离线支持和高安全性,助力打造可靠的 API,推动业务增长。
|
10月前
|
机器学习/深度学习 算法 数据处理
SVM的优缺点是什么
SVM的优缺点是什么
619 9
|
机器学习/深度学习 分布式计算 供应链
Hadoop在特定行业中的应用实例
【8月更文第28天】Hadoop是一个强大的分布式计算框架,能够处理大规模数据集。由于其高可扩展性和成本效益,Hadoop被广泛应用于多个行业中,如金融、医疗保健和零售等。本文将探讨Hadoop在这些行业的具体应用场景和一些成功案例。
458 0
|
人工智能 前端开发 机器人
Coze初体验——为城市创作独特的天气图景
Coze初体验——为城市创作独特的天气图景
Coze初体验——为城市创作独特的天气图景
|
机器学习/深度学习 自然语言处理 算法
什么是自然语言处理的语义理解?
【4月更文挑战第8天】
440 2
什么是自然语言处理的语义理解?
|
机器学习/深度学习 数据采集 人工智能
ICLR 2024:RLHF有了通用平台和基准,天大开源,专攻现实决策场景
【4月更文挑战第21天】天津大学在ICLR 2024发布RLHF新框架Uni-RLHF,以人类反馈引导强化学习,降低奖励函数设计需求,适应现实决策场景。该框架提供通用平台和基准,支持大规模众包注释,促进研究。尽管面临准确捕捉人类反馈、数据质量和多任务处理等挑战,但开源特性加速了学术进步。[链接](https://arxiv.org/abs/2402.02423)
304 0
tauri-app生成应用的图标
tauri-app生成应用的图标
253 0
|
消息中间件 SQL 分布式计算
重新定义性能测试: Apache Flink 重磅开源流计算基准测试框架
每一种引擎有其优势的地方,如何选择适合自己业务的流计算引擎成了一个由来已久的话题。除了比较各个引擎提供的不同的功能矩阵之外,性能是一个无法绕开的评估因素。基准测试(benchmark)就是用来评估系统性能的一个重要和常见的过程。
重新定义性能测试: Apache Flink 重磅开源流计算基准测试框架
|
弹性计算 运维 自然语言处理
30分钟,一键拉起基于LLM + AnalyticDB PostgreSQL构建的企业专属Chatbot
ChatGPT的火爆带动AIGC行业近期非常火热,客户对于智能客服,构建企业知识库用于智能问答,写作助手等相关需求非常旺盛;随着ChatGPT 推出Retrieval plugin的方案推出,向量数据库(企业知识库) + 大语言模型 可以快速帮助企业构建专属的chatbot; 本服务是对文章《云原生数据仓库AnalyticDB(ADB)+LLM:构建AIGC时代下企业专属Chatbot》的一个开源实现部署。模型基于ChatGLM-6B,是由清华大学团队开发的是一个开源的、支持中英双语的对话语言模型,基于 General Language Model (GLM) 架构,具有 62 亿参数。
30分钟,一键拉起基于LLM + AnalyticDB PostgreSQL构建的企业专属Chatbot