LeetCode1,167 两数之和 I,II(uthash.h)

原题目

两数之和I

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/two-sum

两数之和II

给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数。
函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2。
说明:
返回的下标值(index1 和 index2)不是从零开始的。
你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。
示例:
输入: numbers = [2, 7, 11, 15], target = 9
输出: [1,2]
解释: 2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted

题目大意

在一个数组中找两个数,他们之和要等于给定的数target,并返回两个数的下标,前一题是无序的后一题是有序的

题目分析

两数之和II:
方法一,暴力查找法:
方法二,二分查找法:
方法三,双指针法:

两数之和I:
方法一:暴力查找法:
方法二:快排+两数之和II双指针
方法三:哈希表法+c语言uthash.h头文件
注:有时间学习c语言uthash.h
使用步骤:
第一步:包含头文件“uthash.h”

#include

第二步:定义hash结构体

struct my_struct {
int id; /* key */
char name[10];
UT_hash_handle hh; /* makes this structure hashable */
};

第三步:定义hash表指针。这个指针为前面自定义数据结构的指针,并初始化为NULL。

struct my_struct *users = NULL; /* important! initialize to NULL */  

第四步:进行一般的操作。

增加:

int add_user(int user_id, char *name) {  
struct my_struct *s;  
s = malloc(sizeof(struct my_struct));  
s->id = user_id;  
strcpy(s->name, name);  
HASH_ADD_INT( users, id, s ); /* id: name of key field */  
}  

查找:

struct my_struct *find_user(int user_id) {  
struct my_struct *s;  
HASH_FIND_INT( users, &user_id, s ); /* s: output pointer */  
return s;  
}  

删除:

void delete_user(struct my_struct *user) {  
HASH_DEL( users, user); /* user: pointer to deletee */  
free(user); /* optional; it’s up to you! */  
}  

计数:

unsigned int num_users;  
num_users = HASH_COUNT(users);  
printf("there are %u users/n", num_users);  

迭代:

void print_users() {  
struct my_struct *s;  
for(s=users; s != NULL; s=s->hh.next) {  
printf("user id %d: name %s/n", s->id, s->name);  
	}  
}  

排序:

return strcmp(a->name,b->name);  
}  
int id_sort(struct my_struct *a, struct my_struct *b) {  
return (a->id - b->id);  
}  
void sort_by_name() {  
HASH_SORT(users, name_sort);  
}  
void sort_by_id() {  
HASH_SORT(users, id_sort);  
}  

要注意,在uthash中,并不会对其所储存的值进行移动或者复制,也不会进行内存的释放。
参考博客:
https://blog.csdn.net/ym19860303/article/details/9495769
http://www.bubuko.com/infodetail-201428.html
https://www.cnblogs.com/aclove/p/3803110.html

完整代码

两数之和II:
方法一,暴力直接查找法:

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* twoSum(int* numbers, int numbersSize, int target, int* returnSize){
    int *res=(int *)malloc(sizeof(int)*3);
    for(int i=0;i<numbersSize-1;i++)
        for(int j=i+1;j<numbersSize;j++)
        {
            if(numbers[i]+numbers[j]>target)break;
            if(numbers[i]+numbers[j]==target)
            {
                res[0]=i+1;
                res[1]=j+1;
                *returnSize=2;
                return res;
            }
        }
    return false;
}

方法二,二分查找法:

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int search(int *numbers,int val,int left,int right)
{
    while(left<=right)
    {
        int mid=(left+right)/2;
        if(numbers[mid]<val)
            left=mid+1;
        else if(numbers[mid]>val)
            right=mid-1;
        else return mid;
    }
    return -1;
}

int* twoSum(int* numbers, int numbersSize, int target, int* returnSize){
    int *res=(int *)malloc(sizeof(int)*3);
    for(int i=0;i<numbersSize-1;i++)
    {
        int index=search(numbers,target-numbers[i],i+1,numbersSize-1);
        if(index!=-1)
        {
            res[0]=i+1;
            res[1]=index+1;
            *returnSize=2;
            return res;
        }
    }
    return false;
}

方法二,双指针法:

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* twoSum(int* numbers, int numbersSize, int target, int* returnSize){
    int *res=(int *)malloc(sizeof(int)*3);
    int i=0,j=numbersSize-1;
    while(i<j)
    {
        if(numbers[i]+numbers[j]<target)
            i++;
        else if(numbers[i]+numbers[j]>target)
            j--;
        else
        {
            res[0]=i+1;
            res[1]=j+1;
            break;
        }
    }
    *returnSize=2;
    return res;
}

两数之和I
暴力直接查找法:

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* twoSum(int* nums, int numsSize, int target, int* returnSize){
    int *res=(int *)malloc(sizeof(int)*3);
    for(int i=0;i<numsSize-1;i++)
    {
        for(int j=i+1;j<numsSize;j++)
        {
            if(nums[i]+nums[j]==target)
            {
                res[0]=i;
                res[1]=j;
                *returnSize=2;
                return res;
            }
        }
    }
    return false;
}

排序+双指针法:

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
struct Data
{
    int val;
    int index;
};
int cmp(const void *a,const void *b)
{
    return (*(struct Data *)a).val-(*(struct Data *)b).val;
}
int* twoSum(int* nums, int numsSize, int target, int* returnSize){
    struct Data ans[numsSize];
    for(int i=0;i<numsSize;i++)
    {
        ans[i].val=nums[i];
        ans[i].index=i;
    }
    qsort(ans,numsSize,sizeof(ans[0]),cmp);
    int *res=(int *)malloc(sizeof(int)*3);
    int i=0,j=numsSize-1;
    while(i<j)
    {
        if(ans[i].val+ans[j].val<target)
            i++;
        else if(ans[i].val+ans[j].val>target)
            j--;
        else
        {
            res[0]=ans[i].index;
            res[1]=ans[j].index;
            break;
        }
    }
    *returnSize=2;
    return res;
}

哈希表法+uthash.h

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
 //自定义数据结构。每个结构代表一个键-值对,并且,每个结构中要有一个UT_hash_handle成员。
typedef struct hash_node {
    int id;            /* we'll use this field as the key */
    int index;
    UT_hash_handle hh; /* makes this structure hashable */
} hash_node;

int* twoSum(int* nums, int numsSize, int target, int* returnSize){
    int *two_nums = (int *)malloc(sizeof(int)*2);
    //定义hash表指针。这个指针为前面自定义数据结构的指针,并初始化为NULL。
    hash_node *hash_table = NULL, *hash_item1 = NULL, *hash_item2 = NULL;
    for (int i = 0; i < numsSize; i++) {
        // 查找哈希表中是否存在满足和为target的另一个值,若存在直接返回
        int other_id = target - *(nums+i);
       HASH_FIND_INT(hash_table, &other_id, hash_item1);
        if (hash_item1) {
            two_nums[0] = hash_item1->index;
            two_nums[1] = i;
            *returnSize = 2;
            return two_nums;
        }
        // 将本次遍历的值放入哈希表,value为数组下标,key为对应数值
        hash_item2 = (hash_node *)malloc(sizeof(hash_node));
        hash_item2->id = *(nums+i);
        hash_item2->index = i;
        HASH_ADD_INT(hash_table, id, hash_item2);
    }
    return two_nums;
}

总结

题目简单,主要是学习各种解题思路,和uthash.h头文件的运用

你可能感兴趣的:(LeetCode算法题解)