万人千题计划-27

推荐博主

1.英雄哥每天给我们筛选题目,真的非常辛苦,很感谢他,大家可以看看他的专栏,对新手很有帮助,对一些有基础的人更是能温故知新
2.秋名山码民我的小师弟,是个卷王,他的文章也很有趣
3.执久呀我们群里的拼命三郎,老能卷了

千位分隔数

思路:新开一个字符串,遍历字符串,每三位插入一个分隔符

class Solution {
public:
    string thousandSeparator(int n) {
        if(n == 0) return "0";
        string res = to_string(n);
        int size = res.size();
        while(size) {
            size -= 3;
            if(size<=0) break;
            res.insert(size, ".");
        }
        return res;
    }
};

字符串转化后的各位数字之和

思路:字符转成数字,循环求各位数字之和,在循环未结束之前,用把res字符串化后赋给str1

class Solution {
public:
    int getLucky(string s, int k) {
        int res;
        string str1;
        for(auto &c: s) {
            str1 += to_string(c - 'a' + 1);
        }
        for(int i=0; i<k; i++) {
            res = 0;
            for(auto &c1 : str1) {
                res += c1 - '0';//字符串减0后成为整数
            }
            str1 = to_string(res);
        }
        return res;
    }
};

字符串中第二大的数字

思路:用双指针来写,字符串挨个比较,替换就好,
需要注意的是:一开始赋值给max1和max2只能赋-1,我试了INT_MIN,出来时时错的

class Solution {
public:
    int secondHighest(string s) {
        int max1 = -1, max2 = -1;
        for(char &c : s) {
            if(c >='0' && c <= '9') {
                int temp = c - '0';
                if(temp > max1) {
                    max2 = max1;
                    max1 = temp;
                }else if(temp < max1 && temp > max2) {
                    max2 = temp;
                }
            }
        }
        return max2;
    }
};

最小时间差

思路:把字符串转换成数组,进行排序后在比较。同时,进行特殊情况的处理,(23:59, 00:00)
stoi函数:把string类型转化成int类型
s.substr(a,b):返回一个string,包含s中从a开始的b个字符的拷贝

class Solution {
public:
    int findMinDifference(vector<string>& timePoints) {
        int n = timePoints.size();
        int times[n];
        for (int i = 0; i < n; ++i) {
            times[i] = stoi(timePoints[i].substr(0,2))*60 + stoi(timePoints[i].substr(3,2));
        }

        sort(times, times+n);
        int res = INT_MAX;
        for (int i = 0; i < n-1; ++i) {
            res = min(res, times[i+1]-times[i]);
        }
        // 最后一个还要和第一个比较
        res = min(res, 24*60+times[0] - times[n-1]);

        return res;
    }
};

罗马数字转整数

思路:首先建立一个HashMap来映射符号和值,然后对字符串从左到右来,如果当前字符代表的值不小于其右边,就加上该值;否则就减去该值。以此类推到最左边的数,最终得到的结果即是答案

class Solution {
public:
    int romanToInt(string s) {
        unordered_map<char, int> map = {{'I',1}, {'V',5}, {'X',10}, {'L',50}, {'C',100}, {'D',500}, {'M',1000}};
        int sum = map[s.back()];//返回的的是最后一个元素的引用。
        for(int i=s.size()-2; i>=0; i--) {
            sum += (map[s[i]] < map[s[i+1]] ? -map[s[i]] : map[s[i]]);
        }
        return sum;
    }
};

整数转罗马数字

思路:两个字符串数组的值和下标对应,然后用贪心算法

class Solution {
public:
    string intToRoman(int num) {
        int values[]={1000,900,500,400,100,90,50,40,10,9,5,4,1};
        string roman[]={"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"};
        
        string res;
        for(int i=0; i<13; i++){//数组values的大小
            while(num>=values[i]){
                num -= values[i];
                res += roman[i];
            }
        }
        return res;
    }
};

字符串压缩

思路:遍历字符串,将首次遇到的字符加入到res字符串中,
然后跳过重复字符并计数,直到遇到新的字符,
然后把其个数加到res后面,最后进入下一次循环前,将计数重新置1

不过我看他的题目标签说是有双指针,把其他题目搞完之后,看能不能给大家整个双指针的思路出来

class Solution {
public:
    string compressString(string S) {
        string res = "";
        int cnt = 1;
        for(int i=0; i<S.size(); i++) {
            res += S[i];
            while(S[i] == S[i+1]) {
                i++;
                cnt++;
            }
            res += to_string(cnt);
            cnt = 1;
        }
        if(res.size() >= S.size()) return S;
        return res;
    }
};

字符串相加

思路:

class Solution {
public:
    string addStrings(string num1, string num2) {
        int i = num1.length() - 1, j = num2.length() - 1, add = 0;
        string res = "";
        while (i >= 0 || j >= 0 || add != 0) {
            int x = i >= 0 ? num1[i] - '0' : 0;
            int y = j >= 0 ? num2[j] - '0' : 0;
            int result = x + y + add;
            res.push_back('0' + result % 10);
            add = result / 10;
            --i;
            --j;
        }
        // 计算完以后的答案需要翻转过来
        reverse(res.begin(), res.end());
        return res;
    }
};

二进制求和

思路:
1、首先让两个字符串等长,若不等长,在短的字符串前补零,否则之后的操作会超出索引。
2、然后从后到前遍历所有的位数,同位相加,用的是字符相加,利用 ASCII 码,字符在内部都用数字表示,我们不需要知道具体数值,但可知 ‘0’-‘0’ = 0, ‘0’+1=‘1’,以此类推 。(字符的加减,大小比较,实际上都是内部数字的加减,大小比较)

class Solution {
public:
	string addBinary(string a, string b) 
	{
		int asize = a.size(), bsize = b.size();
		while (asize > bsize) {//补齐
			b = '0' + b;
			bsize++;
		}
		while (asize < bsize) {
			a = '0' + a;
			asize++;
		}
		int carry = 0;  //进位
		for (int i = asize - 1; i >= 0; i--) {
			int sum = a[i] - '0' + b[i] - '0' + carry;
			a[i] = (sum) % 2+'0';//本位数值
			carry = sum / 2;//进位更新
		}

        //有溢出
		if (carry > 0) a = '1' + a;
		return a;
	}
};

检查某单词是否等于两单词之和

思路:获取字符串 firstWord、secondWord 和 targetWord 对应的整数的值,然后把前两个相加,判断其和是否等于后者

class Solution {
public:
    bool isSumEqual(string firstWord, string secondWord, string targetWord) {
        int first = 0, second = 0, target = 0;

        for(auto &c : firstWord) first = c - 'a' + first*10;
        for(auto &c : secondWord) second = c - 'a' + second*10;
        for(auto &c : targetWord) target = c - 'a' + target*10;

        return (first + second) == target;
    }
};

字符串相乘

思路:都在代码里了

class Solution {
public:
    string multiply(string num1, string num2) {
        //特殊情况的处理
        if(num1=="0" || num2=="0") return "0";
        if(num1=="1") return num2;
        if(num2=="1") return num1;

        if(num1.size() < num2.size())  //大数×小数,效率高一些
            swap(num1,num2);

        int m = num1.size(), n = num2.size();
        //提前开一个足够大的string,m位数和n位数的乘法结果不会超过m+n位数
        string res(m+n,'0');  
        for(int i = n-1; i>=0; --i){
            if(num2[i]=='0') continue;
            int carry = 0; //进位
            for(int j = m-1; j>=0; --j){
                //先乘后加再进位
                int new_num = (num1[j]-'0')*(num2[i]-'0') + (res[i+j+1]-'0') + carry;
                carry = new_num / 10;
                new_num = new_num % 10;
                res[i+j+1] = char(new_num + '0');
            }
            if(carry > 0) res[i] = char(carry + '0');
        }

        int i = 0;
        while(res[i] == '0') i++;
        return res.substr(i,m+n-i);   //去掉前面多余的0
    }
};

整数转换成英文表示

思路:放弃抵抗,力扣官方的题解(递归)
真有点搞人心态的一道题目,建议大家用有道英语查一下单词

class Solution {
public:
    vector<string> singles = {"", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine"};
    vector<string> teens = {"Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"};
    vector<string> tens = {"", "Ten", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"};
    vector<string> thousands = {"", "Thousand", "Million", "Billion"};

    string numberToWords(int num) {
        if (num == 0) {
            return "Zero";
        }
        string sb;
        for (int i = 3, unit = 1000000000; i >= 0; i--, unit /= 1000) {
            int curNum = num / unit;
            if (curNum != 0) {
                num -= curNum * unit;
                string curr;
                recursion(curr, curNum);
                curr = curr + thousands[i] + " ";
                sb = sb + curr;
            }
        }
        while (sb.back() == ' ') {
            sb.pop_back();
        }
        return sb;
    }

    void recursion(string & curr, int num) {
        if (num == 0) {
            return;
        } else if (num < 10) {
            curr = curr + singles[num] + " ";
        } else if (num < 20) {
            curr = curr + teens[num - 10] + " ";
        } else if (num < 100) {
            curr = curr + tens[num / 10] + " ";
            recursion(curr, num % 10);
        } else {
            curr = curr + singles[num / 100] + " Hundred ";
            recursion(curr, num % 100);
        }
    }
};

从早上八点到下午一点,五个小时,不敢懈怠。
这最后一题,我完成不了,希望大家能够理解,
大致思路的话,就是动态数组配递归
今天的任务就暂且告一段落,准备上课了,大家明天见

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

0泡果奶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值