给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
示例 1:
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
示例 2:
输入:nums = [3,2,4], target = 6
输出:[1,2]
示例 3:
输入:nums = [3,3], target = 6
输出:[0,1]
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/two-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
个人思路:利用快排将数组排序,然后设置双指针逼近target所指值。
个人代码:
注:快排实现要非常熟练,达到能快速默写的程度,个人时间复杂度应该是O(nlogn),空间复杂度O(n),可以优化。
void swap(int *a,int *b){
int temp;
temp=*a;
*a=*b;
*b=temp;
}
void quicksort(int* nums,int left,int right){
if(left>=right)return;
int i=left,j=right;
int pivot=nums[left];
while(i<j){
while(i<j&&nums[j]>pivot)j--;
while(i<j&&nums[i]<=pivot)i++;
swap(&nums[i],&nums[j]);
}
swap(&nums[i],&nums[left]);
quicksort(nums,left,i-1);
quicksort(nums,i+1,right);
}
int* twoSum(int* nums, int numsSize, int target, int* returnSize){
int b[numsSize];
for(int i=0;i<numsSize;i++){
b[i]=nums[i];
}
quicksort(nums,0,numsSize-1);
int i=0,j=numsSize-1;
while(i<j){
if(nums[i]+nums[j]>target&&i<j)j--;
else if(nums[i]+nums[j]<target&&i<j)i++;
else break;
}
if(i<j){
int temp=0;
for(int x=0;x<numsSize;x++){
if(b[x]==nums[i]){i=x;break;}
}
for(int x=numsSize-1;x>=0;x--){
if(b[x]==nums[j]){j=x;break;}
}
int *a=(int *)malloc(sizeof(int)*2);
a[0]=i;
a[1]=j;
*returnSize=2;
return a;
}
else return 0;
}
最优解:利用哈希表
#define MAXSIZE 769/* 选取一个质数即可 */
typedef struct Node
{
//值 - 下标
int value;
int index;
struct Node* next; //保存链表表头
} List;
typedef struct
{
List* hashHead[MAXSIZE];//定义哈希数组的大小
} MyHashMap;
List* isInHash(List* list, int value)
{
List* nodeIt = list;
//通过链表下遍历
while (nodeIt != NULL)
{
if (nodeIt->value == value)
{
return nodeIt;
}
nodeIt = nodeIt->next;
}
return NULL;
}
MyHashMap* myHashMapCreate()
{
int i;
MyHashMap* newHash = (MyHashMap*)malloc(sizeof(MyHashMap));
/* 对链表的头结点赋初值 */
for (i = 0; i < MAXSIZE; i++)
{
newHash->hashHead[i] = NULL;
}
return newHash;
}
void myHashMapPut(MyHashMap* obj, int value, int index)
{
List* it = isInHash(obj->hashHead[abs(value) % MAXSIZE], index);
if (it != NULL)
{
//在表里面更新键值
it->value = value;
}
else
{
//不在表里面
List* newNode = (List*)malloc(sizeof(List));
newNode->value = value;
newNode->index = index;
newNode->next = NULL;
if (obj->hashHead[abs(value) % MAXSIZE] != NULL)
{
//当前头链表不为空,则需要将后续的链表接上
//需要主要这里表头也代表一个数据的值
newNode->next = obj->hashHead[abs(value) % MAXSIZE];
}
//修改头链表
obj->hashHead[abs(value) % MAXSIZE] = newNode;
}
}
int myHashMapGet(MyHashMap* obj, int value)
{
List* it = isInHash(obj->hashHead[abs(value) % MAXSIZE], value);
if (it != NULL)
{
return it->index;
}
return -1;
}
void myHashMapFree(MyHashMap* obj)
{
int i;
List* freeIt;
List* curIt;
for (i = 0; i < MAXSIZE; i++)
{
if (obj->hashHead[i] != NULL)
{
freeIt = NULL;
curIt = obj->hashHead[i];
while (curIt != NULL)
{
freeIt = curIt;
curIt = curIt->next;
free(freeIt);
}
obj->hashHead[i] = NULL;
}
}
free(obj);
}
int* twoSum(int* nums, int numsSize, int target, int* returnSize)
{
MyHashMap* myHashMap = myHashMapCreate();
int i;
int* returnNums = (int*)malloc(sizeof(int) * 2);
*returnSize = 0;
for (i = 0; i < numsSize; i++)
{
int index = myHashMapGet(myHashMap, target - nums[i]);
if(index != -1)
{
*returnSize = 2;
returnNums[0] = index;
returnNums[1] = i;
myHashMapFree(myHashMap);
return returnNums;
}
else
{
myHashMapPut(myHashMap,nums[i], i);
}
}
myHashMapFree(myHashMap);
return returnNums;
}
作者:goodgoodday
链接:https://leetcode.cn/problems/two-sum/solution/liang-shu-zhi-he-cyu-yan-xiang-jie-by-my-gnb4/