高频笔试题1

135 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

力扣:414. 第三大的数 题目链接:第三大的数. 思路:增强for循环、加上if判断,把nums中最大的赋给a,第二大的赋给b,第三大的数赋给c 关键是if判断里的条件,以及值交换的细节

class Solution {
public:
    int thirdMax(vector<int>& nums) {
        long a = LONG_MIN, b = LONG_MIN, c = LONG_MIN;
        for(long num : nums) {
            if(num > a) {
                c = b;
                b = a;
                a = num;
            }else if(a > num && num > b) {
                c = b;
                b = num;
            }else if(b > num && num > c) {
                c = num;
            }
        }
        return c == LONG_MIN ? a : c;//如果 c == LONG_MIN,则没有最小值,输出最大的a
    }
};

力扣:344.反转字符串 题目链接:反转字符串. 思路:利用双指针,左指针指向下标0,右指针指向最右边的下标 当left < right时,交换left和right所指的的元素

class Solution {
public:
    void reverseString(vector<char>& s) {
        int n = s.size();
        for (int left = 0, right = n - 1; left < right; ++left, --right) {
            swap(s[left], s[right]);
        }
    }
};

力扣:2000. 反转单词前缀 题目链接:反转单词前缀. 思路:在word中查找到与ch相同的字符时,做0~(i+1)中的字符反转,

class Solution {
public:
    string reversePrefix(string word, char ch) {
        int left = 0, right = 0;
        for(int i = 0; word[i] != '\0'; ++i) {
            if(word[i] == ch) {
                reverse(begin(word), begin(word) + i + 1);
                break;
            }
        }
        return word;
    }
};

力扣:反转字符串中的元音字母 题目链接:反转字符串中的元音字母. 思路:双指针,一个在左,一个在右,不断遍历,直到left>=right

class Solution {
public:
    string reverseVowels(string s) {
        string word = "aeiouAEIOU";
        int left = 0, right = s.size()-1;
        while(left < right) {
            //防止两边越界,不能及时跳出循环,所以&&left<right
            while(word.find(s[left]) == -1 && left < right) ++left;
            while(word.find(s[right]) == -1 && left < right) --right;
            if(left < right) {
                swap(s[left], s[right]);
                left++;
                right--;
            }
        }
        return s;
    }
};

力扣:翻转单词顺序 题目链接: 翻转单词顺序. 思路:数字那个指针 1、移除多余空格 2、将整个字符串反转 3、将每个单词反转

class Solution {
public:
    // 反转字符串s中左闭又闭的区间[start, end]
    void reverse(string& s, int start, int end) {
        for (int i = start, j = end; i < j; i++, j--) {
            swap(s[i], s[j]);
        }
    }

    //移除多余空格
    void removeExtraSpace(string& s) {
        int slow = 0, fast = 0;
        //去掉字符串前面的空格
        while(s.size() > 0 && fast < s.size() && s[fast] == ' ') {
            fast++;
        }
        
        //去掉字符串中间多余的空格
        for(; fast < s.size(); fast++) {
            if(fast-1 > 0 && s[fast-1] == s[fast] && s[fast] == ' ') {
                continue;
            }else {
                s[slow++] = s[fast];
            }
        }

        //去掉末尾的空格
        if(slow-1 > 0 && s[slow-1] == ' ') {
            s.resize(slow-1);
        }else {
            s.resize(slow);
        }
    }

    string reverseWords(string s) {
        removeExtraSpace(s);
        reverse(s, 0, s.size()-1);

        for(int i=0; i<s.size(); i++) {
            int j=i;

            //查找字符串中的空格,反转单词
            while(j < s.size() && s[j] != ' ') j++;

            reverse(s, i, j-1);
            i=j;
        }
        return s;
    }
};

力扣:翻转字符串里的单词 题目链接:翻转字符串里的单词. 思路:和上一题时一模一样的,说法不同而已

力扣:反转字符串中的单词Ⅲ 题目链接:反转字符串中的单词Ⅲ. 思路:双指针,找到第一个单词时,交换第一个和最后一个字符

class Solution {
public:
    string reverseWords(string s) {
        int len = s.length();
        int i=0;
        while(i < len)
        {
            int start = i;
            while(i < len && s[i] != ' ')
            {
                i++;
            }
            int left = start, right = i-1;
            while(left < right)
            {
                swap(s[left], s[right]);
                left++;
                right--;
            }
            while(i<len && s[i] == ' ')
            {
                i++;
            }
        }
        return s;
    }
};

力扣:反转字符串Ⅱ 题目链接:反转字符串Ⅱ. 思路: 1、每隔 2k 个字符的前 k 个字符进行反转 2、 若剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符 3、 若剩余字符少于 k 个,则将剩余字符全部反转。

class Solution {
public:
    string reverseStr(string s, int k) {
        for (int i = 0; i < s.size(); i += (2 * k)) {
            if (i + k <= s.size()) {
                reverse(s.begin() + i, s.begin() + i + k );
                continue;
            }
            reverse(s.begin() + i, s.begin() + s.size());
        }
        return s;
    }
};

更简洁的代码,和上面的意思差不多

class Solution {
public:
    string reverseStr(string s, int k) {
        int n = s.length();
        for (int i = 0; i < n; i += 2 * k) {
            reverse(s.begin() + i, s.begin() + min(i + k, n));
        }
        return s;
    }
};

力扣:917.仅仅反转字母 题目链接:仅仅反转字母. 思路:不停的交换两指针所指的值就行

class Solution {
public:
    string reverseOnlyLetters(string s) {
        int left = 0;
        int right = s.length() - 1;
        while (left < right) {
            while (!isLetter(s[left]) && left < right) {
                ++left;
            }
            while (!isLetter(s[right]) && left < right) {
                --right;
            }
            swap(s[left], s[right]);
            ++left;
            --right;
        }
        return s;
    }

private:
    bool isLetter(char c) {
        return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
    }
};

力扣:整数反转 题目链接:整数反转. 首先看清楚要求:假设环境不允许存储 64 位整数(有符号或无符号)。 很多人都是用的long long,其实根本不能算做出来了 思路:用if判断res < INT_MIN/10 || res > INT_MAX/10,防止越界

class Solution {
public:
    int reverse(int x) {
        int res = 0;
        while(x!=0)
        {
            if(res < INT_MIN/10 || res > INT_MAX/10)
            {
                return 0;
            }
            int target = x%10;
            x /= 10;
            res = res*10 + target;
        }
        return res;
    }
};