您的位置:首页 > 其它

Leetcode 1 Two Sum

2015-05-27 13:21 387 查看
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));
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: