[日常刷题]leetcode D28

本文深入解析了LeetCode上的四个经典题目,包括字符串反转、元音字母反转、两个数组的交集及其进阶版本。提供了多种C++实现方法,如暴力解决、逆向构造和头尾交换,并详细阐述了每种方法的思路与关键点。

344. Reverse String

Write a function that takes a string as input and returns the string reversed.
Example 1:

Input: "hello"
Output: "olleh"

Example 2:

Input: "A man, a plan, a canal: Panama"
Output: "amanaP :lanac a ,nalp a ,nam A"

Solution in C++:

关键点:

思路:

  • 最简单暴力的方法就是倒着遍历这个字符串,添加到另一个字符串中输出。
  • 之前还查过是否有用迭代器什么的构造字符串的,没仔细看。后来看到discuss里面有人这么做,很开心又学到了。
  • 再就是头尾交换字符的方式。

方法一:暴力

string reverseString(string s) {
        string str="";
        size_t size = s.size();
        for(int i = size - 1; i >= 0; --i)
            str +=s[i];
        
        return str;
    }

方法二:逆向构造

string reverseString(string s) {
        string str(s.rbegin(), s.rend());
        return str;
    }

方法三:头尾交换

string reverseString(string s) {
        size_t size = s.size();
        if (size == 0)
            return s;
        
        for(int i = 0, j = size - 1; i < j; ++i, --j)
        {
            char tmp = s[i];
            s[i] = s[j];
            s[j] = tmp;
        }
        
        return s;
    }

345. Reverse Vowels of a String

Write a function that takes a string as input and reverse only the vowels of a string.
Example 1:

Input: "hello"
Output: "holle"

Example 2:

Input: "leetcode"
Output: "leotcede"

Note:
The vowels does not include the letter “y”.

Solution in C++:

关键点:

  • 字母大小写

思路:

  • 一个从头扫,一个从尾部扫,判断如果两方都为vowel时交换,如果有一方不为则另一方指针移动。
vector<char> vowel={'a','A','e','E','i','I','o','O','u','U'};
    
    bool isVowel(char c){
       size_t size = vowel.size();
        bool flag = false;
        for(int i = 0; i < size; ++i)
        {
            if (c == vowel[i]){
                flag = true;
                break;
            }
        }
        
        return flag;
    }
    
    string reverseVowels(string s) {
        size_t size = s.size();
        if (size == 0)
            return s;
        
        for(int i = 0, j = size - 1; i < j; ++i, --j)
        {
            if (isVowel(s[i]) && isVowel(s[j]))
            {
                char tmp = s[i];
                s[i] = s[j];
                s[j] = tmp;
            } else if (isVowel(s[i])) // s[i]为vowel,s[j]不为
            {
                --i;
            } else if (isVowel(s[j])) // s[j]为vowel,s[i]不为
            {
                ++j;
            }
        }
        return s;
    }

349. Intersection of Two Arrays

Given two arrays, write a function to compute their intersection.
Example 1:

Input: nums1 = [1,2,2,1], nums2 = [2,2]
Output: [2]

Example 2:

Input: nums1 = [4,9,5], nums2 = [9,4,9,8,4]
Output: [9,4]

Note:

  • Each element in the result must be unique.
  • The result can be in any order.

Solution in C++:

关键点:

  • 不能重复

思路:

  • 首先排序,然后一同扫描,当相等是添加到vector中,同时将i,j数值移动,如果相同;不同的时候根据大小判断,移动小的一方。
  • STL

方法一:暴力

vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        sort(nums1.begin(),nums1.end());
        sort(nums2.begin(),nums2.end());
        size_t size1 = nums1.size();
        size_t size2 = nums2.size();
        
        vector<int> result;
        for(int i = 0, j = 0; i < size1 && j < size2;)
        {
            if (nums1[i] == nums2[j])
            {
                result.push_back(nums1[i]);
                while(nums1[i] == nums1[i+1] && (i+1) < size1)
                    ++i;
                while(nums2[j] == nums2[j+1] && (j+1) < size2)
                    ++j;
                ++i;
                ++j;
            } else if(nums1[i] > nums2[j]){
                ++j;
            } else if (nums1[i] < nums2[j]){
                ++i;
            }
        }
        return result;
    }

方法二:STL

vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        std::vector<int> result;
        std::sort(nums1.begin(), nums1.end());
        std::sort(nums2.begin(), nums2.end());
        std::set_intersection(nums1.begin(), nums1.end(), nums2.begin(), nums2.end(), std::back_inserter(result));
        result.erase(std::unique(result.begin(), result.end()), result.end());
        return result;
    }

350. Intersection of Two Arrays II

Given two arrays, write a function to compute their intersection.
Example 1:

Input: nums1 = [1,2,2,1], nums2 = [2,2]
Output: [2,2]

Example 2:

Input: nums1 = [4,9,5], nums2 = [9,4,9,8,4]
Output: [4,9]

Note:

  • Each element in the result should appear as many times as it shows in both arrays.

  • The result can be in any order.
    Follow up:

  • What if the given array is already sorted? How would you optimize your algorithm?

  • What if nums1’s size is small compared to nums2’s size? Which algorithm is better?

  • What if elements of nums2 are stored on disk, and the memory is limited such that you cannot load all elements into the memory at once?

Solution in C++:

关键点:

  • 无需去重

思路:

  • 和上一题的思路一样,就是这题这边不用在相等之后去掉重复相同的。
  • STL利用

方法一:暴力

vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
        sort(nums1.begin(),nums1.end());
        sort(nums2.begin(),nums2.end());
        size_t size1 = nums1.size();
        size_t size2 = nums2.size();
        
        vector<int> result;
        for(int i = 0, j = 0; i < size1 && j < size2; )
        {
            if (nums1[i] == nums2[j])
            {
                result.push_back(nums1[i]);
                ++i;
                ++j;
            } else if(nums1[i] < nums2[j]){
                ++i;
            } else if(nums1[i] > nums2[j]){
                ++j;
            }
        }
        return result;
    }

方法二:STL

vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
        std::vector<int> result;
        std::sort(nums1.begin(), nums1.end());
        std::sort(nums2.begin(), nums2.end());
        std::set_intersection(nums1.begin(), nums1.end(), nums2.begin(), nums2.end(), std::back_inserter(result));
        return result;
    }

小结

今天感觉主要学的就是一些STL的使用方法。今天看到一些东西,有点感悟,在接下来的时间里,我尽量会将代码写的更为优美一点,能够传达思想,向别人描述问题解决方案。(清晰地分解代码、恰当的自解释变量名、注释任何隐含的内容)

知识点

  • STL使用(set)
### 如何用C++在LeetCode的最佳实践 #### 使用C++进行LeetCode编程练习的重要性 由于C++设计感强,STL作为其泛型编程的杰出代表作,在掌握了C++基本语法以及STL中的容器与算法之后,已经具备了解决大多数编程挑战的基础[^1]。 #### 资源推荐 为了更高效地利用C++在LeetCode平台上进行训练,《剑指 Offer》这本书籍及其配套的Python、Java和C++解代码库是一个很好的起点。此资源不仅提供详细的解答思路,还涵盖了多种实现方式,有助于加深对问的理解[^2]。 #### 平台特点 LeetCode平台本身拥有大量精心挑选并按难度分级编排的问集,这些问广泛涉及各种类型的算法和数据结构,非常适合用来提高个人技能水平。更重要的是,这些目通常反映了实际工作中可能遇到的情况或是编程比赛中的典型考形式[^3]。 #### 策略 当准备着手解决问时,建议先浏览一下该所关联的知识领域标签(例如:“数组”,“字符串”,“链表”),这样可以帮助快速定位所需复习的概念和技术要点。针对不同的数据结构类别采取相应的学习方法: - **链表**:重点在于理解指针的工作原理及如何有效地管理内存分配; - **树和图**:则需深入研究递归遍历和其他高级搜索技术来应对更加复杂的逻辑关系[^4]。 ```cpp // 示例:简单的二分查找函数实现 #include <vector> using namespace std; int binarySearch(const vector<int>& nums, int target) { int left = 0; int right = nums.size() - 1; while (left <= right) { int mid = left + (right - left) / 2; // 防止溢出 if (nums[mid] == target) return mid; else if (nums[mid] < target) left = mid + 1; else right = mid - 1; } return -1; // 如果找不到目标,则返回-1表示未找到 } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值