题解|HJ9 提取不重复的整数

提取不重复的整数

https://www.nowcoder.com/practice/253986e66d114d378ae8de2e6c4577c1?tpId=37&rp=1&ru=%2Fta%2Fhuawei&qru=%2Fta%2Fhuawei%2Fquestion-ranking&gioEnter=menu

题目链接|提取不重复的整数

题意:输入一个 int 型整数,按照从右向左的阅读顺序,返回一个不含重复数字的新的整数。保证输入的整数最后一位不是 0 。

数据范围: 1n1081\leq n\leq 10^8

输入描述: 输入一个int型整数

输出描述: 按照从右向左的阅读顺序,返回一个不含重复数字的新的整数

方法一:使用数组记录每个数字是否已经出现 (哈希表思想)

因为字符串的范围在0~9,最多只有10种字符。可以从右向左取出数字的每一位,并维护一个数组记录,当前数字是否已经出现。如果当前字符已经出现,该数字不输出,如果当前字符没有出现过,将记录的数组设成1,并输出当前数字。

时间复杂度:O(N)O(N),解释:遍历一遍字符串的复杂度为O(N)O(N)

空间复杂度:O(M)O(M),解释:需要建立一个数组记录当前字符是否出现,所以复杂度是O(M)O( M)。(M是种类数)

alt

代码

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int ans=0;
int vis[12]={0};
string str;
int main() {
    cin>>str; //按照字符串类型输入更好处理
    int len=str.length(); //数字长度
    for(int i=len-1;i>=0;i--){
        int num=(int)str[i]; //每一位
        if(vis[num]==0) {
            vis[num]=1; //将出现过的数字标记上
            cout<<str[i]; //在此之前没有出现过,所以该位可以输出
        }
    }
    cout<<endl;
    return 0;
}

方法二:使用STL中的集合来统计,输出集合中未出现过的数字

每次向集合中添加元素时,如果集合中已经有该元素,不会重复添加;如果集合中没有该元素,则会添加新元素。反向遍历数字的同时询问该数字是否已经存在于集合中,如果没有出现过,就向集合添加这个数字并输出;否则忽略该数字。在C/C++中set的实现是红黑树。

时间复杂度:O(NlogN)O(NlogN), 解释:单次插入的复杂度为O(logN)O(logN),操作NN次,所以复杂度为O(NlogN)O(NlogN)

空间复杂度:O(M)O(M),解释:使用树的数据结构维护节点的复杂度为O(M)O(M),其中MM为种类数目。

alt

代码

#include <cstdio>
#include <cstring>
#include <iostream>
#include <set>
using namespace std;
string str;
set<char> nums;
int main() {
    cin>>str; //按照字符串类型输入更好处理
    int len=str.length();
    for(int i=len-1;i>=0;i--){
        if(nums.find(str[i])!=nums.end()){ //假设集合中已经出现过了就直接忽略
            continue;
        } else {
            cout<<str[i]; //否则直接输出当前数字
            nums.insert(str[i]); //将当前数字添加到集合里
        }    
    }
    cout<<endl;
    return 0;
}
全部评论
看了你的讲解很有启发,不过方法一好像有些问题,int ans=0;int vis[12]={0};string str;这三个作为全局变量能够通过测试,但是作为局部变量就会出错。经过调试发现int num=(int)str[i];中num得到的是0-9对应的ascall码,数值都在48-57之间。上面数组作为局部变量时因为vis[48-57]的位置未初始化为0,所以不能通过测试,而数组作为全局变量时48-57的位置会自动初始化为0,即使数组下标错误也能得到正确结果。改良的方法是(int)str[i]; int num = str[i] - '0';将num由ascall码转化为对应的字符。
4 回复 分享
发布于 2022-07-28 00:44

相关推荐

小灰呵呵呵:网签还是纸质三方啊
点赞 评论 收藏
分享
评论
7
1
分享
牛客网
牛客企业服务