Leetcode 504.七进制数

2023-09-13 00:13:41

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

示例 1:

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

示例 2:

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

我的答案:

一、信息

1.目的实现十进制向其他进制的转换。

2.原理:公式

3.一段运算过程

4.根据后面的一段话不难看出根据作者的意思就是用栈的数据结构来存储每次辗转相除后的余数然后输出

二、分析

问题出现

问题1:如何实现栈的构造。

问题2:然后如何把余数压入栈

问题3:如何把余数放出栈

我的答案:

为了实现这个功能,我们可以使用栈数据结构来帮助我们进行进制转换。以下是我们的思考和分析过程:

  1. 检查特殊情况: 如果 num 是 0, 我们可以直接返回 "0"。
  2. 处理符号: 如果 num 是负数,我们记下这个信息,并将 num 转化为正数进行处理。
  3. 数字转换: 不断将 num 除以 7,并将余数放入栈中,直到 num 为 0。
  4. 构建结果字符串: 然后我们可以从栈中取出元素(这将给我们一个反向的 7 进制表示)并构建结果字符串。如果最初的 num 是负数,我们在结果字符串前加上负号。

流程图: 

源代码:

C语言:

#include <stdio.h>
#include <stdlib.h>

char* convertToBase7(int num) {
    if (num == 0) return "0";

    char *result = (char *)malloc(12); // sufficient size to store the result as string
    int index = 0;
    int is_negative = 0;
    if (num < 0) {
        is_negative = 1;
        num = -num;
    }

    int stack[10]; // stack to hold the digits
    int top = -1;

    while (num > 0) {
        stack[++top] = num % 7;
        num /= 7;
    }

    if (is_negative) {
        result[index++] = '-';
    }

    while (top >= 0) {
        result[index++] = '0' + stack[top--];
    }

    result[index] = '\0';

    return result;
}

int main() {
    printf("%s\n", convertToBase7(100)); // Output: "202"
    printf("%s\n", convertToBase7(-7));  // Output: "-10"
    return 0;
}

C++:

#include <iostream>
#include <stack>
#include <string>

std::string convertToBase7(int num) {
    if (num == 0) return "0";

    std::stack<int> s;
    std::string result;
    bool is_negative = false;

    if (num < 0) {
        is_negative = true;
        num = -num;
    }

    while (num > 0) {
        s.push(num % 7);
        num /= 7;
    }

    if (is_negative) {
        result += '-';
    }

    while (!s.empty()) {
        result += '0' + s.top();
        s.pop();
    }

    return result;
}

int main() {
    std::cout << convertToBase7(100) << std::endl; // Output: "202"
    std::cout << convertToBase7(-7) << std::endl;  // Output: "-10"
    return 0;
}

 JAVA:

import java.util.Stack;

public class Main {
    public static String convertToBase7(int num) {
        if (num == 0) return "0";

        Stack<Integer> stack = new Stack<>();
        StringBuilder result = new StringBuilder();
        boolean isNegative = false;

        if (num < 0) {
            isNegative = true;
            num = -num;
        }

        while (num > 0) {
            stack.push(num % 7);
            num /= 7;
        }

        if (isNegative) {
            result.append('-');
        }

        while (!stack.isEmpty()) {
            result.append(stack.pop());
        }

        return result.toString();
    }

    public static void main(String[] args) {
        System.out.println(convertToBase7(100)); // Output: "202"
        System.out.println(convertToBase7(-7));  // Output: "-10"
    }
}

三者的区别: 

虽然这三种实现都使用了栈数据结构来实现整数到7进制的转换,但它们之间还是存在一些差别:

1. **语言特性和语法**:
   - **C**:需要手动管理内存分配和释放,并且使用字符数组来构建结果字符串。
   - **C++**:可以利用 STL 中的栈和字符串,它们有助于简化代码和减少错误。
   - **Java**:利用了 Java 的 Stack 类和 StringBuilder 类,Java 为内存管理提供了自动垃圾回收。

2. **内存分配**:
   - **C**:在堆上分配内存来存储结果字符串,并在最后添加了空字符('\0')来标记字符串的结束。
   - **C++**:使用了 std::string 类,它内部管理内存分配和释放。
   - **Java**:StringBuilder 类用来动态构建字符串,Java 虚拟机负责管理内存。

3. **错误处理和特殊情况的处理**:
   - 所有三种实现都检查了 `num` 是否为0的特殊情况,并对负数进行了处理。

4. **栈的使用**:
   - 在所有的实现中,我们都使用栈来存储7进制的数字,这样可以确保在构建结果字符串时,我们能够从最高位开始(因为栈是先入后出的数据结构)。

5. **代码的可读性和维护性**:
   - **C**:需要更多的代码来管理内存和数组索引。
   - **C++**:由于使用了 STL,代码比 C 更简洁和易读。
   - **Java**:由于使用了类和对象,代码是高度结构化和模块化的,易于读取和维护。

综上所述,虽然核心逻辑是相似的,但由于语言的特性和差异,每种实现都有其独特的方面和处理方式。

解决问题:

英雄师傅的答案:

英雄师傅的思路:

源代码:

char *convertToBase7(int num) {
    char *ret = (char *)malloc(sizeof(char) * 100); // 分配一个足够大的字符数组来存储结果
    int size = 0; // 用于跟踪结果字符串的当前长度
    int stk[50], top = 0; // 用于将数字的7进制表示反向存储在栈中

    if (num < 0) { // 如果输入的数字为负数
        num = -num; // 取其绝对值
        ret[size++] = '-'; // 在结果字符串中加入负号
    }

    if (num == 0) { // 如果输入的数字为0
        ret[size++] = '0'; // 直接将字符'0'存储在结果字符串中
    }

    while (num) { // 将数字的7进制表示逆序存储在栈中
        stk[top++] = num % 7; // 取余数并存储在栈中
        num /= 7; // 将数字除以7,以进行下一位的计算
    }

    while (top) { // 从栈中取出数字的7进制表示,并存储在结果字符串中
        ret[size++] = stk[--top] + '0'; // 逆序取出并转换为字符
    }

    ret[size] = '\0'; // 在结果字符串的最后添加终止符,以表示字符串的结束

    return ret; // 返回存储7进制表示的字符串
}

Leetcode题解:

C语言: 

char * convertToBase7(int num){
    if (num == 0) {
        return "0";
    }
    bool negative = num < 0;
    num = abs(num);
    char * digits = (char *)malloc(sizeof(char) * 32);
    int pos = 0;
    while (num > 0) {
        digits[pos++] = num % 7 + '0';
        num /= 7;
    }
    if (negative) {
        digits[pos++] = '-';
    }
    for (int l = 0, r = pos - 1; l < r; l++, r--) {
        char c = digits[l];
        digits[l] = digits[r];
        digits[r] = c;
    }
    digits[pos] = '\0';
    return digits;
}

C++:

class Solution {
public:
    string convertToBase7(int num) {
        if (num == 0) {
            return "0";
        }
        bool negative = num < 0;
        num = abs(num);
        string digits;
        while (num > 0) {
            digits.push_back(num % 7 + '0');
            num /= 7;
        }
        if (negative) {
            digits.push_back('-');
        }
        reverse(digits.begin(), digits.end());
        return digits;
    }
};

JAVA:

class Solution {
    public String convertToBase7(int num) {
        if (num == 0) {
            return "0";
        }
        boolean negative = num < 0;
        num = Math.abs(num);
        StringBuffer digits = new StringBuffer();
        while (num > 0) {
            digits.append(num % 7);
            num /= 7;
        }
        if (negative) {
            digits.append('-');
        }
        return digits.reverse().toString();
    }
}

总结:

两种方式的比较:

使用栈存储和Leetcode提供的方法(字符串拼接+反转)在实现上有一些区别。让我们逐一探讨这两种方法的优缺点:

### 1. 使用栈存储方法

#### 优点:
1. **自然的顺序**:栈是一种后进先出(LIFO)的数据结构,它可以自然地按照从高位到低位的顺序存储七进制的数字。
2. **无需字符串反转**:由于栈的性质,我们可以按照高位到低位的顺序提取数字,避免了字符串反转这一步骤。
3. **代码可读性**:使用栈可以使代码具有更好的结构和可读性,特别是对于初学者来说,可以更清晰地展示算法的逻辑。

#### 缺点:
1. **额外的空间**:使用栈意味着我们需要额外的空间来存储数据。
2. **可能的额外时间开销**:栈操作(压栈和弹栈)可能会增加一些时间开销。

### 2. Leetcode提供的方法(字符串拼接+反转)

#### 优点:
1. **空间效率**:直接使用字符串进行操作,避免了使用额外数据结构导致的空间开销。
2. **简洁性**:代码相对简洁,尤其是在处理字符串拼接和反转的编程语言中。

#### 缺点:
1. **需要字符串反转**:由于从低位开始构建结果字符串,因此需要在最后执行一次字符串反转操作,增加了一些时间复杂度。
2. **代码可读性**:虽然代码较为简洁,但对于初学者来说,理解代码的逻辑可能需要更多时间。

### 总结:
- **栈存储方法**更适用于想要清晰展示算法逻辑的场合,它可以更自然地表达算法中的步骤,但可能会带来一些额外的时间和空间开销。
- **Leetcode的方法**则更为简洁和高效,尤其是在字符串操作相对便捷的编程语言中
但可能需要更多的时间来理解和分析代码的逻辑。

从这道题目中我们能学到什么?

这道题目可以帮助我们学到以下几点:

1. **基本数学知识**:它强调了我们对数字进制转换的理解,特别是如何从十进制转换为其他进制。这是计算机科学中一个非常基本但重要的概念。

2. **算法设计和实现**:通过设计算法来解决这个问题,我们可以学习如何将抽象的数学问题转化为具体的算法和代码实现。

3. **条件处理**:本题目涉及正数和负数的处理,这能帮助我们理解如何在算法中处理不同的条件和边界情况。

4. **数据结构的应用**:如果我们选择用栈来解决这个问题,我们可以学到如何在实际问题中使用栈这一数据结构。同时,通过比较栈和字符串拼接方法,我们可以学习如何根据特定问题选择合适的数据结构。

5. **代码优化**:通过比较不同的解决方案(如使用栈与直接使用字符串),我们可以学习如何分析和比较不同方法的时间和空间复杂度,从而进行代码优化。

6. **问题分析和解决策略**:我们可以学习如何分析问题,确定解决策略,然后逐步实现。例如,在这个问题中,我们首先需要分析如何从数学的角度解决问题,然后再将解决方案转换为代码。

7. **代码的可读性和简洁性**:我们可以学习如何编写简洁而可读的代码,以便于其他人(或未来的我们)理解和维护代码。

8. **实际应用**:在计算机科学中,进制转换是一个常见的操作。通过学习如何实现这样的转换,我们可以更好地理解和应用这一概念于实际情境中。

总的来说,这道题目可以作为一个很好的练习来提升我们的编程技能和算法设计能力。

更多推荐

Pytest自动化测试 - 必知必会的一些插件

【软件测试行业现状】2023年了你还敢学软件测试?未来已寄..测试人该何去何从?【自动化测试、测试开发、性能测试】Pytest拥有丰富的插件架构,超过800个以上的外部插件和活跃的社区,在PyPI项目中以“pytest-*”为标识。本篇将列举github标星超过两百的一些插件进行实战演示。插件库地址:http://pl

浅谈 AI 大模型的崛起与未来展望:马斯克的 xAI 与中国产业发展

文章目录💬话题📋前言🎯AI大模型的崛起🎯中国AI产业的进展与挑战🎯AI大模型的未来展望🧩补充📝最后💬话题北京时间7月13日凌晨,马斯克在Twiiter上宣布:“xAI正式成立,去了解现实。”马斯克表示,推出xAI的原因是想要“了解宇宙的真实本质”。GhatGPT横空出世已有半年,国内外“百模大战”愈演愈

内网IP端口提供外网连接访问?快解析动态域名与内网映射P2P穿透方案

我们在本地搭建服务器及发布互联网时,可以通过动态域名的方式联网。DDNS原理是用固定的域名代替变化IP,实现局域网发布公网,是适合本地动态IP环境的使用。但当本地没有公网IP时,如果解析绑定到内网IP,将内网IP端口提供外网连接访问?这时我们就需要用到内网映射的方式了。动态域名与内网映射是二种不同的方法,分别针对动态公

Apache Hive安装部署详细图文教程

目录一、ApacheHive元数据1.1HiveMetadata1.2HiveMetastore二、Metastore三种配置方式​2.1内嵌模式​2.2本地模式​2.3远程模式​三、Hive部署实战3.1安装前准备3.2Hadoop与Hive整合3.3远程模式安装3.3.1安装MySQL3.3.2Hive安装3.4启

汉威科技亮相2023上海传感器展,智能传感新品引关注

作为全球三大传感器展之一的中国(上海)国际传感器技术与应用展览会,被誉为全球传感器行业发展的风向标,每届展会都会展出数以万计的行业尖端传感新技术和新产品。今年,第8届中国(上海)国际传感器技术与应用展览会于9月13至15日在上海跨国采购会展中心起航。此次展会上,车载传感、激光和柔性传感等智能传感领域的新品受到了关注。近

100天精通Python(可视化篇)——第99天:Pyecharts绘制多种炫酷K线图参数说明+代码实战

文章目录专栏导读一、K线图介绍1.说明2.应用场景二、配置说明三、K线图实战1.普通k线图2.添加辅助线3.k线图鼠标缩放4.添加数据缩放滑块5.K线周期图表书籍推荐专栏导读🔥🔥本文已收录于《100天精通Python从入门到就业》:本专栏专门针对零基础和需要进阶提升的同学所准备的一套完整教学,从0到100的不断进阶

【Python 数据科学】Dask.array:并行计算的利器

文章目录1.什么是Dask.array?1.1Dask简介1.2Dask.array概述1.3Dask.array与Numpy的对比2.安装与基本用法2.1安装Dask库2.2创建Dask数组2.3数组计算与操作3.Dask.array的分块策略3.1数组分块的优势3.2调整分块大小3.3数据倾斜与rebalance4

OpenMMLab MMYOLO目标检测应用示例与常见问题(三)

基于MMYOLO的电离图实时目标检测基准数据集数字电离图是获取实时电离层信息的最重要方式。电离层结构检测对于准确提取电离层关键参数具有重要的研究意义。本研究利用中国科学院在海南、武汉和怀来获得的4311张不同季节的电离图建立数据集。使用labelme手动注释包括LayerE、Es-l、Es-c、F1、F2和Spread

【SpringBoot系列】Spring cloud Gateway 动态路由到底有多简单

🤵‍♂️个人主页:@香菜的个人主页,加ischongxin,备注csdn✍🏻作者简介:csdn认证博客专家,游戏开发领域优质创作者,华为云享专家,2021年度华为云年度十佳博主🐋希望大家多多支持,我们一起进步!😄如果文章对你有帮助的话,欢迎评论💬点赞👍🏻收藏📂加关注+系列文章:SpringBoot学习大

Hdoop伪分布式集群搭建

文章目录Hadoop安装部署前言1.环境2.步骤3.效果图具体步骤(一)前期准备(1)ping外网(2)配置主机名(3)配置时钟同步(4)关闭防火墙(二)正文(1)配置hosts列表(2)SSH免密钥登录配置①master虚拟机上②slave01虚拟机上③slave02虚拟机上④验证免密登录(3)安装JDK(4)安装部

机器学习实战(01)-人工智能概要

1发展历程20世纪50年代:人工智能概念诞生1956年,“人工智能”这个术语由麦卡锡在达特茅斯会议上首次提出主要研究逻辑和推理,以及如何在机器上模拟人类智能20世纪60年代:知识表达期开始研究知识表达,使用谓词逻辑来表达知识开发可以解题的专家系统,例如Dendral专家系统20世纪70年代:知识库期研究汇集知识到知识库

热文推荐