OJ - Two Sum && Three Sum

Two Sum:
题目的主题为搜索,那么我们就需要使用便于搜索的数据结构来解题:哈希表:

h = hash()
for num in vec:
    sub = target - num
    if sub in h:
        return (num, sub)
    else:
        h.insert(num)

主体思想为:边插边找,找到了就直接return,这样可以避免单个元素的重复使用:
C++代码为:

vector<int> twoSum(vector<int>& nums, int target) {
        vector<int> result;
        unordered_map<int, int> currentMap;

        auto size = nums.size();
        for (int i = 0; i < size; ++i) {
            int tar = target - nums[i];

            unordered_map<int, int>::iterator it = currentMap.find(tar);

            if (it != currentMap.end()) {
                result.push_back(it->second);
                result.push_back(i);
            } else {
                currentMap.insert(make_pair(nums[i], i));
            }
        }

        return result;
    }

Three Sum:
这题还是以搜索为主,但是需要找的是所有的(a,b,c)使得a+b+c=0,而不是一个特定的数【本质差不多】,并且不能重复。
这题可以先把数组排序(时间复杂度为O(N*logN))再来对排序过后的数组进行搜索【稍微有一些二分的思想】:

result = container
sort(nums)
for i=0; i < size; ++i:
    target = -nums[i]
    if target < 0:
        break
    head = i+1
    rear = nums.size() - 1
    while head < rear:
        sum = nums[head] + nums[rear]
        if sum > target:
            rear--
        else if sum < target:
            head++
        else:
            result.add(nums[i], nums[head], nums[rear])
            while head < rear && nums[head] == nums[head+1]:
                head++
            while head < rear && nums[rear] == nums[rear]:
                rear--
            head++
            rear--
    while i < size && nums[i] == nums[i+1]:
        i++;
return result

C++代码:

vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> result;
        sort(nums.begin(), nums.end());
        int size = nums.size() - 2;
        for (int i = 0; i < size; ++i) {
            int target = -nums[i];
            if (target < 0) {
                break;
            }
            int head = i + 1;
            int rear = size + 1;
            while (head < rear) {
                int sum = nums[head] + nums[rear];
                if (sum < target) {
                    head++;
                } else if (sum > target) {
                    rear--;
                } else {
                    vector<int> current(3, 0);
                    current[0] = nums[i];
                    current[1] = nums[head];
                    current[2] = nums[rear];
                    result.push_back(current);
                    while (head < rear && nums[head] == nums[head+1]) head++;
                    while (head < rear && nums[rear] == nums[rear-1]) rear--;
                    head++;
                    rear--;
                }
            }
            while (i < size && nums[i] == nums[i+1]) i++;
        }
        return result;
    }

1.上面的代码里面break代码代表数组后面的数已经是正数了,不可能再加起来等于0.
2.第一个for循环为了逐个数进行判断,第一个while循环为了找到所有符合a+b+c=0条件的数【二分】
3.第三个和第四个循环是为了去除第二个数和第三个数的重复
4.最后一个循环是为了去除第一个数的重复。

猜你喜欢

转载自blog.csdn.net/nia305/article/details/80092232
今日推荐