leetcode/nowcoder-huawei-3-排序

本文包含了多个编程题目,涉及对表记录的合并、字符串的字典序排序、查找字符串的兄弟单词以及合并区间等数据处理问题。每个题目都提供了输入输出示例和解题思路,主要利用C++中的数据结构如map和vector,以及排序算法进行解决。
摘要由CSDN通过智能技术生成

3.排序

HJ8. 合并表记录

  1. 描述

    数据表记录包含表索引index和数值value(int范围的正整数),请对表索引相同的记录进行合并,即将相同索引的数值进行求和运算,输出按照index值升序进行输出。
    
    提示:
    0 <= index <= 11111111
    1 <= value <= 100000
    
    输入描述:
    先输入键值对的个数n(1 <= n <= 500)
    接下来n行每行输入成对的index和value值,以空格隔开
    输出描述:
    输出合并后的键值对(多行)
    示例1
    输入:
    	4
    	0 1
    	0 2
    	1 2
    	3 4
    输出:
    	0 3
    	1 2
    	3 4
    示例2
    输入:
    	3
    	0 1
    	0 2
    	8 9
    输出:
    	0 3
    	8 9
    
  2. 思路

    key-value存入map,指针输出

  3. 代码

    #include <iostream>
    using namespace std;
    #include <map>
    int main() {
        map<int,int> nums;
        int n;
        cin >> n;
        int index,num;
        for(int i = 0; i < n; i++) {
            cin >> index >> num;
            nums[index] += num;
        }
        for(auto iter = nums.begin(); iter != nums.end(); iter++) {
            printf("%d %d\n",iter->first,iter->second);
        }
        return 0;
    }
    

HJ14. 字符串排序

  1. 描述

    给定 n 个字符串,请对 n 个字符串按照字典序排列。
    
    数据范围: 
    1≤n≤1000,字符串长度满足,1≤len≤100 
    输入描述:
    输入第一行为一个正整数n(1≤n≤1000),下面n行为n个字符串(字符串长度≤100),字符串中只含有大小写字母。
    输出描述:
    数据输出n行,输出结果为按照字典序排列的字符串。
    示例1
    输入:
    	9
    	cap
    	to
    	cat
    	card
    	two
    	too
    	up
        boat
    	boot
    输出:
    	boat
    	boot
    	cap
    	card
    	cat
    	to
    	too
    	two
    	up
    
  2. 思路

    输入到vector,排序

  3. 代码

    #include <iostream>
    using namespace std;
    #include <vector>
    #include <algorithm>
    int main() {
        int n;
        cin >> n;
        string str;
        vector<string> strs;
        for(int i = 0; i < n; i++) {
            cin >> str;
            strs.push_back(str);
        }
        sort(strs.begin(),strs.end());
        cout << endl;
        cout << endl;
        for(auto s:strs) {
            cout << s << endl;
        }
        return 0;
    }
    

HJ27. 查找兄弟单词

  1. 描述

    定义一个单词的“兄弟单词”为:交换该单词字母顺序(注:可以交换任意次),而不添加、删除、修改原有的字母就能生成的单词。
    兄弟单词要求和原来的单词不同。例如: ab 和 ba 是兄弟单词。 ab 和 ab 则不是兄弟单词。
    现在给定你 n 个单词,另外再给你一个单词 x ,让你寻找 x 的兄弟单词里,按字典序排列后的第 k 个单词是什么?
    注意:字典中可能有重复单词。
    数据范围:1≤n≤1000 ,输入的字符串长度满足1≤len(str)≤10,1≤k<n
    输入描述:输入只有一行。 先输入字典中单词的个数n,再输入n个单词作为字典单词。 然后输入一个单词x 最后后输入一个整数k
    输出描述:
    第一行输出查找到x的兄弟单词的个数m 第二行输出查找到的按照字典顺序排序后的第k个兄弟单词,没有符合第k个的话则不用输出。
    示例1
    输入:
    	3 abc bca cab abc 1
    输出:
    	2
    	bca
    示例2
    输入:
    	6 cab ad abcd cba abc bca abc 1
    输出:
    	3
    	bca
    说明:
    abc的兄弟单词有cab cba bca,所以输出3
    经字典序排列后,变为bca cab cba,所以第1个字典序兄弟单词为bca      
    
  2. 思路

    找到所有兄弟单词,并输出

    先匹配其他单词的长度,并判断是否是兄弟单词

  3. 代码

    #include <iostream>
    using namespace std;
    #include <vector>
    #include <algorithm>
    
    void findStr(vector<string> strs, string str, int n) {
        vector<string> bro;
        string tmp1,tmp;
        tmp = str;
        sort(tmp.begin(),tmp.end());
        cout << tmp << endl;
        int len = str.size();
        for(int i = 0; i < strs.size(); i++) {
            tmp1 = strs[i];
            if(tmp1.size() != len)   continue;
            sort(tmp1.begin(),tmp1.end());
            if(tmp.compare(tmp1) == 0 && str.compare(strs[i]) != 0) {
                bro.push_back(strs[i]);
            }
        }
        cout << bro.size() << endl;
        if(bro.size()) cout << bro[n-1] << endl;
    }
    
    int main() {
        int n;
        cin >> n;
        vector<string> strs;
        string str;
        for(int i = 0; i < n; i++) {
            cin >> str;
            strs.push_back(str);
        }
        sort(strs.begin(), strs.end());
        cin >> str;
        cin >> n;
        findStr(strs, str, n);
        return 0;
    }
    

NC37. 合并区间

  1. 描述

    给出一组区间,请合并所有重叠的区间。
    请保证合并后的区间按区间起点升序排列。
    
    数据范围:区间组数 0≤n≤2×10 ,区间内 的值都满足 0≤val≤2×10 
     
    要求:空间复杂度 O(n),时间复杂度 O(nlogn)
    进阶:空间复杂度 O(val),时间复杂度O(val)
    
    示例1
    输入:
    	[[10,30],[20,60],[80,100],[150,180]]
    返回值:
    	[[10,60],[80,100],[150,180]]
    示例2
    输入:
    	[[0,10],[10,20]]
    返回值:
    	[[0,20]]
    
  2. 思路

    从string获取范围,先排序,确定范围后压入结果队列

  3. 代码

    #include <iostream>
    using namespace std;
    #include <vector>
    #include <algorithm>
    
    struct Interval {
        int start;
        int end;
        Interval() : start(0), end(0) {}
        Interval(int s, int e) : start(s), end(e) {}
    };
    
    
    class Solution {
    public:
        vector<Interval> getIntervalVec(string str) {
            vector<Interval> range;
            pair<int,int> p;
            char ch;
            int n = -1;
            int tmp;
            for(int i = 0; i < str.size(); i++) {
                ch = str[i];
                if (ch == ',' && str[i-1] != ']') {
                    p.first = tmp;
                    tmp = 0;
                } else if(ch == ']' && str[i-1] != ']') {
                    p.second = tmp;
                    range.push_back(Interval(p.first,p.second));
                    tmp = 0;
                } else if ((ch - '0') <= 9 && (ch - '0') >= 0) {
                    tmp = tmp * 10 + (ch - '0');
                }        
            }
            return range;        
        }
        vector<Interval> merge(string str) {
            vector<Interval> ranges = getIntervalVec(str);
            return merge(ranges);        
        }
    
        vector<Interval> merge(vector<Interval> &intervals) {
            if(intervals.size() <= 1)   return intervals;
            vector<Interval> ranges = intervals;
            sort(ranges.begin(),ranges.end(),[](Interval a, Interval b){return a.start < b.start;});
            for(auto p:ranges) {
                printf("<%d,%d>\n",p.start,p.end);
            }
            int min = -1 ,max = -1;
            vector<Interval> res;
            min = ranges[0].start;
            max = ranges[0].end;
            for(int i = 1; i < ranges.size(); i++) {
                if(max < ranges[i].start) {
                    res.push_back(Interval(min, max));
                    min = ranges[i].start;
                    max = ranges[i].end;
                    continue;
                }
                if(max >= ranges[i].start && max <= ranges[i].end)  max = ranges[i].end;
                else if(min >= ranges[i].start && min <= ranges[i].end) min = ranges[i].start;
            }
            res.push_back(Interval(min, max));
            printf("[");
            for(int i = 0; i < res.size()-1; i++) {
                printf("[%d,%d],",res[i].start,res[i].end);
            }
            int n = res.size() - 1;
            if(res.size() > 0) printf("[%d,%d]",res[n].start,res[n].end);
            printf("]");
            return res;
        }
    };
    
    void getRange(string str) {
        vector<vector<int>> ranges;
        char ch;
        int n = -1;
        int tmp;
        for(int i = 0; i < str.size(); i++) {
            ch = str[i];
            if (ch == ',' && str[i-1] != ']') {
                ranges.push_back({});
                n++;
                ranges[n].push_back(tmp);
                tmp = 0;
            } else if(ch == ']' && str[i-1] != ']') {
                ranges[n].push_back(tmp);
                tmp = 0;
            } else if ((ch - '0') <= 9 && (ch - '0') >= 0) {
                tmp = tmp * 10 + (ch - '0');
            }        
        }
        sort(ranges.begin(),ranges.end());
        for(auto p:ranges) {
            printf("<%d,%d>\n",p[0],p[1]);
        }
        int min = -1 ,max = -1;
        vector<vector<int>> res;
        min = ranges[0][0];
        max = ranges[0][1];
        for(int i = 1; i < ranges.size(); i++) {
            if(max < ranges[i][0]) {
                res.push_back({min, max});
                min = ranges[i][0];
                max = ranges[i][1];
                continue;
            }
            if(max >= ranges[i][0] && max <= ranges[i][1])  max = ranges[i][1];
            else if(min >= ranges[i][0] && min <= ranges[i][1]) min = ranges[i][0];
        }
        res.push_back({min, max});
        printf("[");
        for(int i = 0; i < res.size()-1; i++) {
            printf("[%d,%d],",res[i][0],res[i][1]);
        }
        n = res.size() - 1;
        if(res.size() > 0) printf("[%d,%d]",res[n][0],res[n][1]);
        printf("]");
    }
    
    int main() {
        string str;
        cin >> str;
        getRange(str);
        Solution sol;
        cout << endl;
        sol.merge(str);
        return 0;
    }
    

HJ68. 成绩排序

  1. 描述

    给定一些同学的信息(名字,成绩)序列,请你将他们的信息按照成绩从高到低或从低到高的排列,相同成绩
    都按先录入排列在前的规则处理。
    例示:
    jack      70
    peter     96
    Tom       70
    smith     67
    从高到低  成绩 
    peter     96 
    jack      70 
    Tom       70 
    smith     67
    从低到高
    smith     67
    jack      70
    Tom       70 
    peter     96
    
    注:0代表从高到低,1代表从低到高
    
    数据范围:人数:1≤n≤200 
    进阶:时间复杂度:O(nlogn) ,空间复杂度:O(n)
    
    输入描述:
    第一行输入要排序的人的个数n,第二行输入一个整数表示排序的方式,之后n行分别输入他们的名字和成绩,以一个空格隔开
    输出描述:
    按照指定方式输出名字和成绩,名字和成绩之间以一个空格隔开
    
    示例1
    输入:
    	3
    	0
    	fang 90
    	yang 50
    	ning 70
    输出:
    	fang 90
    	ning 70
    	yang 50
    
    示例2
    输入:
    	3
    	1
    	fang 90
    	yang 50
    	ning 70
    输出:
    	yang 50
    	ning 70
    	fang 90
    
  2. 思路

    将数据以key-value 的形式放入vector,自定义sort,使之按照value排序

  3. 代码

    #include <iostream>
    using namespace std;
    #include <vector>
    #include <algorithm>
    
    class Person
    {
    public:
        string name;
        int score;
        int index;
        Person(string s, int num, int i): name(s), score(num), index(i) {}
    };
    
    
    void sortScore(vector<Person> nums, int increase) {
        cout << endl;
        if(increase)
            sort(nums.begin(),nums.end(),[](Person a, Person b){
                if(a.score == b.score)  return  a.index < b.index;
                return a.score < b.score;
            });
        else
            sort(nums.begin(),nums.end(),[](Person a, Person b){
                if(a.score == b.score)  return  a.index < b.index;
                return a.score > b.score;
            });
        for(auto iter = nums.begin(); iter != nums.end(); iter++) {
            cout << iter->name;
            printf(" %d\n",iter->score);
        }
    }
    
    int main() {
        int n;
        int increase;
        cin >> n;
        cin >> increase;
        vector<Person> nums;
        string name;
        int score;
        for(int i = 0; i < n; i++) {
            cin >> name >> score;
            nums.push_back(Person(name, score, i));
        }
        sortScore(nums,increase);
        return 0;
    }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值