[日常刷题]leetcode D30

本文解析了LeetCode上的三道经典题目:FirstUniqueCharacterinaString、FindtheDifference和NthDigit,提供了C++实现的解决方案,并总结了XOR运算在求奇数个数问题中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

387. First Unique Character in a String

Given a string, find the first non-repeating character in it and return it’s index. If it doesn’t exist, return -1.
Examples:

s = "leetcode"
return 0.

s = "loveleetcode",
return 2.

Note: You may assume the string contain only lowercase letters.

Solution in C++:

关键点:

  • 第一个非重复字符

思路:

  • 因为是字母所以就很有限了,大概思想是先扫描一遍string s,记录其中的字母个数,然后再扫描一遍记录判断其是否大小为1,是即为第一个非重复字符的下标。
int firstUniqChar(string s) {
        map<char, int> maps;
   
        for(auto ch : s){
            map<char, int>::iterator it = maps.find(ch);
            if (it != maps.end()){
                ++maps[ch];
            } else{
                maps[ch] = 1;
            }    
        }
        
        size_t size = s.size();
        for(int i = 0; i < size; ++i)
            if(maps[s[i]] == 1)
                return i;
        return -1;      
    }

389. Find the Difference

Given two strings s and t which consist of only lowercase letters.

String t is generated by random shuffling string s and then add one more letter at a random position.

Find the letter that was added in t.

Example:

Input:
s = "abcd"
t = "abcde"

Output:
e

Explanation:
'e' is the letter that was added.

Solution in C++:

关键点:

  • 多余字母

思路:

  • 实际就是找另一个字符串中多出来的那个字母,我感觉我现在做这类题目已经有种惯性了,直接就是先扫描string s,记录其中每个字母的个数。然后再扫描一遍string t,将记录中对应字母个数-1,再判断是否小于0,是则找到了;
  • 然后看到了discuss里面的一个答案,让我又想起了XOR的用法,就是获取到奇数个个数的东西。

方法一:暴力扫描

char findTheDifference(string s, string t) {
        vector<int> characters(26,0);
        
        for(auto ch : s){
            ++characters[ch-'a'];
        }
        
        for(auto ch : t){
            if (characters[ch-'a'] == 0)
                return ch;
            else{
                if (--characters[ch-'a'] < 0)
                    return ch;
            }
        }
    }

方法二:XOR

char findTheDifference(string s, string t) {
        char res = 0;
        for(auto ch : s)
            res ^= ch;
        
        for(auto ch : t)
            res ^= ch;
        
        return res;
    }

400. Nth Digit

Find the n t h n^{th} nth digit of the infinite integer sequence 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, …
Note:
n is positive and will fit within the range of a 32-bit signed integer (n < 2 31 2^{31} 231).

Example 1:

Input:
3

Output:
3

Example 2:

Input:
11

Output:
0

Explanation:
The 11th digit of the sequence 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ... is a 0, which is part of the number 10.

Solution in C++:

关键点:

  • 哈哈哈

思路:

  • 用一个数组存i位数字的第一个数字,然后用另外一个数组存i位数字的总位数。这两个数组需要自己初始化,因为范围是int所以这两个数组的大小并不大。基本算法大家自己列举几个就看出来规律了。然后根据输入的n判断属于哪个位数段,再计算出数字加偏移即可得出数字。看了下大家大致的思想都差不多,对于处理得到num[offset]有的直接转换成字符串得到,我的方法可能朴素了点,就直接是数字方法获取,所以自己写了获取num的offset位的方法。
位数第一个数字总个数总位数
i 1 0 i − 1 10^{i-1} 10i19 * 1 0 i − 1 10^{i-1} 10i19 * 1 0 i − 1 10^{i-1} 10i1 * i
class Solution {
public:
    int getDigit(int num, int index, int totalDigit){
        if (index > totalDigit)
            return -1;
        
        int i = totalDigit - index;
        int count = 0;
        while(num){
            if (count == i)
                return num % 10;
            num /= 10;
            ++count;   
        }
    }
    
    int findNthDigit(int n) {
        // startNum[i] 表示当数字位数为i时第一个数 eg.startNum[1] = 1
        vector<int> startNum{0};
        // totalDigit[i] 表示当数字位数为i时总位数 eg.totalDigit[1] = 9
        vector<long long> totalDigit{0};
        
        long long sumDigit = 9;
        long long num = 1;

        for(int i = 1; num < INT_MAX; ++i){
             startNum.push_back(num);
             totalDigit.push_back(sumDigit);
             sumDigit = 9 * pow(10,i) * (i+1);
             num = pow(10,i);
        }

        size_t size = totalDigit.size();

        for(int i = 1; i < size; ++i){
            long long tmp = n - totalDigit[i];
            if (tmp <= 0){
                int index = n / i;  // 第几个数
                int offset = n % i; // 数字中第几位
                // 计算数字

                num = startNum[i] + index;
                if (i == 1)
                    --num;

                if (offset == 0){
                    if (i == 1)
                        return num;
                    return getDigit(num-1,i,i);
                } else{
                    return getDigit(num,offset,i);
                }
            }
            n -= totalDigit[i];
        }
    }
};

小结

今天前面两题基本没花什么大时间,主要最后一题的逻辑处理部分花了不少时间,对于index的处理以及offset的处理。然后再就是long long越界问题的处理。然后对于XOR的方法有加深了印象。

知识点

  • XOR求奇数个数的问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值