leetcode之two sum

下定决心终于开始了leetcode之旅,先给自己打打气。
下面是two sum的问题

Given an array of integers, find two numbers such that they add up to a specific target number.

The function twoSum should return indices of the two numbers such that
they add up to the target, where index1 must be less than index2.
Please note that your returned answers (both index1 and index2) are
not zero-based.

You may assume that each input would have exactly one solution.

Input: numbers={2, 7, 11, 15}, target=9
Output: index1=1, index2=2

刚刚开始看到题的时候,发现这题也太简单了点,直接双重循环不就可以了,面试的时候哪个公司会出这样的题呢。。。。。。事实证明我还是too young too naive。。。。time limit exceeded, On2 是不能忍受的

然后自己又读了一遍题,并没有发现有什么不同,并且我在想如果输入的序列是有顺序的可能还会有什么算法,但是题目中并没有给出。看起来就是只有循环到底这一种方法。。。。哎,大学上到这个程度,真的是很伤自尊的。

无奈,看了一下讨论,发现了一个词hashtable,what?我可是从来没有遇到过这种东西啊,它能干啥?看了几遍还是没有搞懂,压根以前就没有听说过这种东西。。。

后来看到了另外一种算法,就是先排序,然后再进行验证,首先用一种效率比较高的算法,将无序数组排序,然后验证时需要定义前后两个指针,两个相加,如果大于integer,那么右边的指针向左移,如果小于integer,则左边的指针右移,这样的算法时间可以达到 O(nlog(n)) ,既然已经有提交成功了的,那么我也就姑且试试吧。
260ms accepted

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
#include <stdio.h>
#include <stdlib.h>

 void quickSort(int *nums, int left, int right){
    if (left >= right)
        return ;
    int tmp = nums[left];
    int index = left;

    int low = left;
    int high = right;
    while (left < right){ 
        while (left < right && nums[right] > tmp){
            right--;
        }
        nums[index] = nums[right];
        index = right;
        while (left < right && nums[left] <= tmp){
            left++;
        }
        nums[index] = nums[left];
        index = left;
    }
    nums[index] = tmp;
    quickSort(nums, low, left-1);
    quickSort(nums, left+1, high);
}

int* twoSum(int* nums, int numsSize, int target) {
    int* index = (int *)malloc(2 * sizeof(int));
    int* snums = (int *)malloc(numsSize * sizeof(int));
    for (int m = 0; m < numsSize; m++){
        snums[m] = nums[m];
    }
    quickSort(nums, 0, numsSize-1);
    int i = 0; int j = numsSize - 1;
    for (i = 0, j = numsSize -1 ; i != j; ){
        if (nums[i] + nums[j] > target)
            j--;
        else if (nums[i] + nums[j] < target)
            i++;
        else
            break;    
    }

    int flag = -1;
    for (int k = 0; k < numsSize; k++){
        if (snums[k] == nums[i] && flag != 1){
            index[0] = k;
            flag = 1;
            continue;
        }
        if (snums[k] == nums[j] && flag != 0){
            index[1] = k;
            flag = 0;
        }
    }
    int tmp;

    index[0]++;
    index[1]++;
    if (index[0] > index[1]){
        tmp = index[0];
        index[0] = index[1];
        index[1] = tmp;
    }

    return index;
}

C语言的效率应该要比这个更高,但是目前用排序再验证的方法应该就是这个级别了。

完成了accepted,心里也就有底了,然后下一步就是开始钻研hashtable是个什么东东,看了几个c++的代码后,我才慢慢地懂了,原来是一种能够达到 O(1) 的搜索方法,如果在hashtable中搜索一个东西,只要知道索引的值那么搜索的时间效率非常高,基本上是直接定位,之前建立索引表的方法的效率则是 O(n) ,看到大家都是java,c++的hashtable做的,考虑到python是一门高级语言,我觉得用字典的话,应该实现的效率会非常高,果不其然68ms,accepted

class Solution:
    # @param {integer[]} nums
    # @param {integer} target
    # @return {integer[]}
    def twoSum(self, nums, target):
        i =  0
        dnums = {}
        while i < len(nums):
            dnums[nums[i]] = i
            i = i + 1

        i = 0
        result = []
        while i < len(nums):
            if dnums.get(target-nums[i]) and dnums.get(target-nums[i]) != i:
                if dnums.get(target-nums[i]) > i:
                    result.append(i+1)
                    result.append(dnums.get(target-nums[i])+1)
                    break
                else:
                    result.append(i+1)
                    result.append(dnums.get(target-nums[i])+1)
                    break
            i = i + 1

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值