• (双指针,哈希表) leetcode 3. 167. Two Sum,lintcode 382. 125 Valid Palindrome,344


    Two sum:

    哈希表解法;

    class Solution {
    public:
        vector<int> twoSum(vector<int>& nums, int target) {
            //只有唯一的一个解,且nums里的数不能重复使用
            //hash
            unordered_map<int, int> index;
            for(int i=0; i<nums.size(); i++)
                index[nums[i]] = i;
            
            for(int i=0; i<nums.size(); i++){
                int left = target - nums[i];
                if(index.count(left) && index[left]!=i)
                    //能在index中找到另一个数与nums[i]相加为target
                    return {i, index[left]};    //返回索引
            }
            return {};  //找不到解,返回空vector
        }
    };

    注意这两个元素不能是相同的。

    解法一:二分查找法,逐一取数组中的值,然后second = target - numbers[i] , 用二分查找法求第二个值。

    时间复杂度:O(nlongn)

    class Solution {
    public:
        vector<int> twoSum(vector<int>& numbers, int target) {
            //二分查找
            vector<int> result;
            int n = numbers.size();
            for(int i=0; i<n;i++){
                int second = target - numbers[i];
                int l = i+1, r = n-1;
                while(l<=r){
                    int mid = (l+r)/2;
                    if(second < numbers[mid]){
                        //在左半部分
                        r = mid-1;
                    }
                    else if(second > numbers[mid]){
                        //在右半部分
                        l = mid+1;
                    }
                    else{
                        //返回索引,从1开始
                        result.push_back(i+1);
                        result.push_back(mid+1);
                        break;
                    }
                }
                if(result.size()==2) break;
            }
            return result;
        }
    };

    解法三:对撞指针

    使用两个指针,若nums[i] + nums[j] > target 时,i++; 若nums[i] + nums[j] < target 时,j -- 。

    时间复杂度:O(n)

    class Solution {
    public:
        vector<int> twoSum(vector<int>& numbers, int target) {
            int n = numbers.size();
            int l = 0, r = n-1;
            while(l<r){
                if(numbers[l] + numbers[r] == target){
                    int res[2] = {l+1, r+1};
                    return vector<int>(res, res+2);
                }
                else if(numbers[l] + numbers[r] < target)
                    l++;
                else
                    r--;
            }
    throw invalid_argument("The input has no solution."); } };
    class Solution {
    public:
        vector<int> twoSum(vector<int>& nums, int target) {
            //只有唯一的一个解,且nums里的数不能重复使用
            //hash
            unordered_map<int, int> index;
            for(int i=0; i<nums.size(); i++)
                index[nums[i]] = i;
            
            for(int i=0; i<nums.size(); i++){
                int left = target - nums[i];
                if(index.count(left) && index[left]!=i)
                    //能在index中找到另一个数与nums[i]相加为target
                    return {i, index[left]};    //返回索引
            }
            return {};  //找不到解,返回空vector
        }
    };

    Two sum's follow up : 

    //
    //  main.cpp
    //  Two sum 的follow up
    // 在数组中找两个元素使它们的和大于9,返回元素对的个数
    // sort + 双指针
    // ans = ans + (j-i);   当前有j-i个元素对大于target
    //
    #include<bits/stdc++.h>
    using namespace std;
    int main() {
        // insert code here...
        vector<int> nums{4,5,3,6,1,2,7};
        int target = 8;
        sort(nums.begin(), nums.end());
        int left = 0, right = nums.size()-1;
        int ans = 0;
        while(left < right){
            if(nums[left] + nums[right] > target){
                ans += (right - left);
                right--;
            }
            else{
                left++;
            }
        }
        cout << "ans: "<<ans<<endl;;
        return 0;
    }

    对撞指针的另一个题目:

    空串也认为是回文串。若 isalnum() == true,则为字母或数字;使用toupper()将其转换为大写。

    #include <ctype.h>
    class Solution {
    public:
        bool isPalindrome(string s) {
            int l = 0, r = s.size()-1;
            while(l<r){
                //跳过非字母和数字的字符
                while(!isalnum(s[l]) && l<r)
                   l++;
                while(!isalnum(s[r]) && l<r)
                   r--;
                //将字母或数字都转化为大写来比较是否相同
                if(toupper(s[l]) != toupper(s[r]))
                   return false;
                l++;
                r--;
            }
            return true;
        }
    };

    344 Reverse String

    还蛮简单的,用了对撞指针的思想,交换首尾对应指针所指的元素的值。

    class Solution {
    public:
        string reverseString(string s) {
            int l = 0, r = s.size()-1;
            int mid = (l+r)/2;
            for(int i=0;i<=mid;i++){
                swap(s[l], s[r]);
                l++;
                r--;
            }
            return s;
        }
    };

    345 

    翻转元音字母:aeiouAEIOU

    class Solution {
    public:
        bool is_vowel(char c){
            if((c=='a')||(c=='e')||(c=='i')||(c=='o')||(c=='u')||(c=='A')||(c=='E')||(c=='I')||(c=='O')||(c=='U'))
                return true;
            else 
                return false;
        }
        string reverseVowels(string s) {
            int n = s.size();
            int l = 0, r = n-1;
            
            while(l<r){
                while(!is_vowel(s[l]) && l<r)
                    l++;
                while(!is_vowel(s[r]) && l<r)
                    r--;
                swap(s[l], s[r]);
                l++;
                r--;
            }
            return s;
        }
    };

    11

    class Solution {
    public:
    int maxArea(vector<int> &height) {
        int m = 0;
        int i = 0, j = height.size() - 1;
        while (i < j) {
            //m = max(m, (j - i) * min(height[i], height[j]));
            //height[i] < height[j] ? i++ : j--;
            if(height[i] < height[j]){
                m = max(m, (j - i) * height[i]);
                i++;
            }
            else{
                 m = max(m, (j - i) * height[j]);
                 j--;
            }
        }
        return m;
    }
    };

  • 相关阅读:
    8皇后问题
    求1到n,n个整数的全排列
    求最小周期串
    如何用java完成一个中文词频统计程序
    蛇形矩阵
    第一个算法程序
    java 继承练习题8
    java 继承练习题7
    java 继承练习题6
    java 继承练习题5
  • 原文地址:https://www.cnblogs.com/Bella2017/p/10146882.html
Copyright © 2020-2023  润新知