LeetCode(454. 4Sum II&383. Ransom Note&15. 3Sum&18. 4Sum)

Preface

This is a new day to continue my Hash Table journey.
Learn something new and keep reviewing what I learnt before.

1. 4Sum II

LeetCode Link: 454. 4Sum II
Given four integer arrays nums1, nums2, nums3, and nums4 all of length n, return the number of tuples (i, j, k, l) such that:

0 <= i, j, k, l < n
nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0

Analysis and Solution

Unordered Map

LeetCode C++ as followings Unordered Map

class Solution {
public:
   int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) {
        unordered_map<int, int> umap; //include key and value;key:sum of a+b,value:frequency of a+b
        // traverse A and B;assign sum and frequency to map
        for (int a : A) {//assign per element to a from A,for loop
            for (int b : B) {//assign per element to b from B,for loop
                umap[a + b]++;//get the sum of a+b;and record frequency of a+b
            }
        }
        int count = 0; //  record the frequency of a+b+c+d
        // traverse C and D,if 0-(c+d) appeared in the map,record frequency of a+b+c+d
        for (int c : C) {//same as before
            for (int d : D) {//same as before
                if (umap.find(0 - (c + d)) != umap.end()) {// If the given key exists in unordered_map it returns an iterator to that element otherwise it returns the end of the map iterator.
                    count += umap[0 - (c + d)];//count=count+umap[0 - (c + d)]
                }
            }
        }
        return count;

    }
};

2. Ransom Note

LeetCode Link: 383. Ransom Note
Given two strings ransomNote and magazine, return true if ransomNote can be constructed by using the letters from magazine and false otherwise.

Each letter in magazine can only be used once in ransomNote.

Analysis and Solution

Double For

LeetCode C++ as followings Double For

class Solution {
public:
    bool canConstruct(string ransomNote, string magazine) {
        for (int i = 0; i < magazine.length(); i++) {//traverse magazine
            for (int j = 0; j < ransomNote.length(); j++) {//traverse ransomNote
                if (magazine[i] == ransomNote[j]) {//find same element of two
                    ransomNote.erase(ransomNote.begin() + j); // delete this element in ransomNote (1)string& erase ( size_t pos = 0, size_t n = npos );(2)iterator erase ( iterator position );(3)iterator erase ( iterator first, iterator last );
                    break;
                }
            }
        }
        // if ransomNote is empty,which means the elements of magazine can form ransomNote
        if (ransomNote.length() == 0) {
            return true;
        }
        return false;

    }
};

Hash Array

LeetCode C++ as followings Hash Array

class Solution {
public:
    bool canConstruct(string ransomNote, string magazine) {
        int record[26] = {0};//define a hash array
        //if ransomNote > magazine, it definitely cannot form ransomNote from magazine
        if (ransomNote.size() > magazine.size()) {
            return false;
        }
        for (int i = 0; i < magazine.length(); i++) {//traverse magazine
            // record the frequency of per element in the magazine
            record[magazine[i]-'a'] ++;//use ASCII to calculate ,and get the location of the record, +1 there
        }
        for (int j = 0; j < ransomNote.length(); j++) {//traverse ransomNote
            record[ransomNote[j]-'a']--;//same as before , -1 at the area of the array
            if(record[ransomNote[j]-'a'] < 0) {//if <0,which means some elements cannot match by magazine
                return false;
            }
        }
        return true;


    }
};

3. 3Sum

LeetCode Link: 15. 3Sum
Given an integer array nums, return all the triplets [nums[i], nums[j], nums[k]] such that i != j, i != k, and j != k, and nums[i] + nums[j] + nums[k] == 0.

Notice that the solution set must not contain duplicate triplets.

Analysis and Solution

Hash Table

LeetCode C++ as followings Hash Table

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> result;//define a result array
        sort(nums.begin(), nums.end());//sort the array
        // define a = nums[i], b = nums[j], c = -(a + b),find a+b+c=0
        for (int i = 0; i < nums.size(); i++) {//traverse array
            if (nums[i] > 0) {//a+b+c cannot = 0, if first element of array > 0
                break;
            }
            if (i > 0 && nums[i] == nums[i - 1]) { //remove the repeat value of a
                continue;
            }
            unordered_set<int> set;//define a hash set 
            for (int j = i + 1; j < nums.size(); j++) {//traverse j
                if (j > i + 2
                        && nums[j] == nums[j-1]
                        && nums[j-1] == nums[j-2]) { // remove the repeat value of b
                    continue;
                }
                int c = 0 - (nums[i] + nums[j]);//define c
                if (set.find(c) != set.end()) {//find function If the given key exists in unordered_map it returns an iterator to that element otherwise it returns the end of the map iterator.
                    result.push_back({nums[i], nums[j], c});//The C++ function std::vector::push_back() inserts new element at the end of vector and increases size of vector by one.
                    set.erase(c);// remove the repeat value of c
                } else {
                    set.insert(nums[j]);//insert b
                }
            }
        }
        return result;

    }
};

Double Pointer

LeetCode C++ as followings Double Pointer

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
       vector<vector<int>> result;//define a array
        sort(nums.begin(), nums.end());//sort array
        // define a = nums[i], b = nums[left], c = nums[right]
        for (int i = 0; i < nums.size(); i++) {//traverse array
            // a+b+c cannot = 0, if first element of array > 0
            if (nums[i] > 0) {
                return result;
            }
            // wrong way to remove repeat value,which will ignore-1,-1,2
            /*
            if (nums[i] == nums[i + 1]) {
                continue;
            }
            */
            // remove repeat value a
            if (i > 0 && nums[i] == nums[i - 1]) {
                continue;
            }
            int left = i + 1;//define b
            int right = nums.size() - 1;//define c
            while (right > left) {
                // if remove repeat value here,the situation 0,0,0 ,which lead right<=left ,may ignore 000
                /*
                while (right > left && nums[right] == nums[right - 1]) right--;
                while (right > left && nums[left] == nums[left + 1]) left++;
                */
                if (nums[i] + nums[left] + nums[right] > 0) right--;//move c pointer
                else if (nums[i] + nums[left] + nums[right] < 0) left++;//move b pointer
                else {
                    result.push_back(vector<int>{nums[i], nums[left], nums[right]});//The C++ function std::vector::push_back() inserts new element at the end of vector and increases size of vector by one.
                    // remove the repeat value of b and c
                    while (right > left && nums[right] == nums[right - 1]) right--;
                    while (right > left && nums[left] == nums[left + 1]) left++;

                    // double pointer retarcted after found answer
                    right--;
                    left++;
                }
            }

        }
        return result;
    }
};

4. 4Sum

LeetCode Link: 18. 4Sum
Given an array nums of n integers, return an array of all the unique quadruplets [nums[a], nums[b], nums[c], nums[d]] such that:

0 <= a, b, c, d < n
a, b, c, and d are distinct.
nums[a] + nums[b] + nums[c] + nums[d] == target
You may return the answer in any order.

Analysis and Solution

Double Pointer

LeetCode C++ as followings Double Pointer

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        vector<vector<int>> result;//define a array named result 
        sort(nums.begin(), nums.end());//sort array
        for (int k = 0; k < nums.size(); k++) {//traverse array
            // delete the branch;
            if (nums[k] > target && nums[k] >= 0) {// K should be smallest num after sorting, if K>0,and K>target,it cannot get target with others.
            	break; //  use Break to return together at last
            }
            //  remove the repeat value of K
            if (k > 0 && nums[k] == nums[k - 1]) {//judge K ?= K-1
                continue;//The continue statement breaks one iteration (in the loop), if a specified condition occurs, and continues with the next iteration in the loop.
            }
            for (int i = k + 1; i < nums.size(); i++) {//traverse i
                //  delete the second branch
                if (nums[k] + nums[i] > target && nums[k] + nums[i] >= 0) {//if K+i>0,and K+i>target,it cannot get target with others(4 nums).
                    break;
                }

                // remove the repeat value of nums[i]
                if (i > k + 1 && nums[i] == nums[i - 1]) {//judge i ?= i-1
                    continue;//The continue statement breaks one iteration (in the loop), if a specified condition occurs, and continues with the next iteration in the loop.
                }
                int left = i + 1;//define a pointer(left)
                int right = nums.size() - 1;//define a  pointer(right)
                while (right > left) {//judge in a loop
                    // nums[k] + nums[i] + nums[left] + nums[right] > target ;it would overflow 
                    if ((long) nums[k] + nums[i] + nums[left] + nums[right] > target) {
                        right--;//move right to a smaller num
                    // nums[k] + nums[i] + nums[left] + nums[right] < target ;it would overflow
                    } else if ((long) nums[k] + nums[i] + nums[left] + nums[right]  < target) {
                        left++;//move left to a bigger one
                    } else {
                        result.push_back(vector<int>{nums[k], nums[i], nums[left], nums[right]});//The C++ function std::vector::push_back() inserts new element at the end of vector and increases size of vector by one.
                        // remove the repeat value of nums[left] amd nums[right]
                        while (right > left && nums[right] == nums[right - 1]) right--;
                        while (right > left && nums[left] == nums[left + 1]) left++;

                        // double pointers move to middle at the same time after found answer
                        right--;
                        left++;
                    }
                }

            }
        }
        return result;

    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值