码迷,mamicode.com
首页 > 其他好文 > 详细

Leetcode 1 Two Sum

时间:2015-05-27 13:57:02      阅读:161      评论:0      收藏:0      [点我收藏+]

标签:

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

即快速地从一个数组中找出两个数字,使它们之和等于给定值。

可以直接暴力求解,但是时间复杂度为O(N^2),在leetcode上提交显示超时。

int* twoSum(int* nums, int numsSize, int target) {
	int i,j;
	int re[2];
	for(i=0;i<numsSize-1;i++)
		for(j=i+1;j<numsSize;j++)
		{
			if(nums[i]+nums[j]==target)
			{
				re[0]=i+1;
				re[1]=j+1;
			}
		}
		return re;
}
可以先对数组排序,再利用二分查找法,设置两个指针,在数组上遍历一次就可以得到结果。时间复杂度O(nlogn)+O(n)=O(nlogn)

我先写了如下代码:

int Partion(int a[],int p,int r)
{
	int i=p;
	int j=r;
	int key=a[i];
	while(i<j)
	{
		while(i<j && a[j]>=key)
			j--;
		if(i<j)
			a[i]=a[j];
		while(i<j && a[i]<=key)
			i++;
		if(i<j)
			a[j]=a[i];
	}
	a[i]=key;
	return i;
} 

void QuickSort(int a[],int p,int r)
{
	int q;
	if(p<r)
	{
		q=Partion(a,p,r);
		QuickSort(a,p,q-1);
		QuickSort(a,q+1,r);
	}
}
int* twoSum(int* nums, int numsSize, int target) {
	int i,j,i1,j1,m;
	int re[2]={-1,-1};

	int *new_nums = (int *)malloc(numsSize * sizeof(int));
	if(new_nums==NULL)
	{
		printf("malloc fail!");
		return;
	}
	for(m=0;m<numsSize;m++)
		new_nums[m]=nums[m];

	QuickSort(new_nums,0,numsSize-1);
	
	for(i=0,j=numsSize-1; i<j; )
	{
		if( (new_nums[i]+new_nums[j]) == target)
		{
			//寻找原来的位置
			for(m=0;m<numsSize;m++)
			{
				if(new_nums[i]==nums[m])
				{
					i1 = m;
					break;
				}
			}
			for(m=0;m<numsSize;m++)
			{
				if(new_nums[j]==nums[m]&&m!=i1)
				{
					j1 = m;
					break;
				}
			}

			re[0]=(i1<j1)?(i1+1):(j1+1);
			re[1]=(i1>j1)?(i1+1):(j1+1);

			return re;
		}
		else if(new_nums[i]+new_nums[j] < target)
			i++;
		else
			j--;
	}
}
事实上,由于要查找两个数在原来数组的位置时,又要遍历一次,算法的复杂度依然是O(n^2);如果要降低复杂度,可以在快排的时候就记录下排序后数组元素的位置,代码如下:(这段代码可在leetcode讨论中看到)

void swap(int *x, int *y)
{
    int temp;
    temp = *x;
    *x = *y;
    *y = temp;
    return;

}
int search(int numbers[], int target, int low, int high)
{
    if (low > high)
        return -1;
    int mid = low + (high - low) / 2;
    if (target < numbers[mid])
        return search(numbers, target, low, mid - 1);
    else if (target > numbers[mid])
        return search(numbers, target, mid + 1, high);
    else
        return mid;
}
void sort(int numbers[], int orders[], int low, int high)
{
    int key, keyOrder, i, j, ran;
    if (low < high)
    {
        ran = (low + high) / 2;
        swap(&numbers[ran], &numbers[low]);
        swap(&orders[ran], &orders[low]);
        key = numbers[low];
        keyOrder = orders[low];
        i = low + 1;
        j = high;
        while (i <= j)
        {
            while ((i <= high) && (numbers[i] <= key))
                i++;
            while ((j >= low) && (numbers[j] > key))
                j--;
            if (i < j)
            {
                swap(&numbers[i], &numbers[j]);
                swap(&orders[i], &orders[j]);
            }

        }
        swap(&numbers[low], &numbers[j]);
        swap(&orders[low], &orders[j]);
        sort(numbers, orders, low, j - 1);
        sort(numbers, orders, j + 1, high);
    }

}
int *twoSum(int numbers[], int n, int target) {
    int i = 0, j = -1;
    int *index = (int *)malloc(2 * sizeof(int));
    int len = n;
    int *orders = (int *)malloc(n * sizeof(int));
    for (i = 0; i < len; i++)
    {
        orders[i] = i + 1;
    }
    sort(numbers, orders, 0, len - 1);
    for (i = 0; i < len; i++)
    {
        j = search(numbers, target - numbers[i], i + 1, len - 1);
        if (j > -1)
            break;
    }
    if (j > -1)
    {
        if (orders[i] > orders[j])
        {
            index[0] = orders[j]; index[1] = orders[i];
        }
        else
        {
            index[0] = orders[i]; index[1] = orders[j];
        }
        return index;
    }
    else
        return NULL;
}
下面附上Java版本写法

import java.util.Arrays;
import java.util.Hashtable;

public class Solution1 {
	//336ms
	public static int[] twoSum(int[] nums,int target){
		int[] out = new int[2];
		int[] new_nums = new int[nums.length];
		int i1=-2,j1=-2;
		new_nums = Arrays.copyOf(nums, nums.length);
		Arrays.sort(new_nums);
		
		for(int i = 0, j = nums.length-1;i < j;){
			if(new_nums[i]+new_nums[j] == target){
				//寻找原来的位置
				for(int m=0;m<nums.length;m++)
				{
					if(new_nums[i]==nums[m])
					{
						i1 = m;
						break;
					}
				}
				for(int m=0;m<nums.length;m++)
				{
					if(new_nums[j]==nums[m]&&m!=i1)
					{
						j1 = m;
						break;
					}
				}
				out[0]=(i1<j1)?(i1+1):(j1+1);
				out[1]=(i1>j1)?(i1+1):(j1+1);
				return out;
			}
			else if(new_nums[i]+new_nums[j] < target){
				i++;
			}
			else
				j--;
		}
		return out;
	}
	//344ms
	public static int[] twoSum_1(int[] nums,int target)
	{
		int[] out = new int[2];
		Hashtable<Integer,Integer> new_nums = new Hashtable<Integer,Integer>();
		for(int i = 0;i<nums.length;i++){
			Integer n = new_nums.get(nums[i]);
			if(n == null)
				new_nums.put(nums[i], i);
			n = new_nums.get(target-nums[i]);
			if(n!=null && n<i){
				out[0] = n+1;
				out[1] = i+1;
				return out;
			}
		}
		return out;
	}
	
	public static void main(String args[]){
		int nums[] = {150,24,79,50,88,345,3};
		int[] out;
		out = Solution1.twoSum_1(nums,138);
		System.out.print(Arrays.toString(out));
	}
}







Leetcode 1 Two Sum

标签:

原文地址:http://blog.csdn.net/u010498696/article/details/46045381

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!