给定一个整数数组 nums
和一个目标值 target
,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
class Solution { public int[] twoSum(int[] nums, int target) { int tempt; HashMap<Integer, Integer> hashMap=new HashMap<>(); for(int i=0;i<nums.length;i++){ tempt=target-nums[i]; if(hashMap.containsKey(tempt)){ return new int[]{hashMap.get(tempt),i}; } hashMap.put(nums[i],i); } return null; } }
整体时间复杂度为O(N),长度也为O(N).
使用hashmap进行映射,hashmap查找速度为O(1),因为hashmap是通过映射来查找的
通过建立一个hash表。hash表的空间复杂度为N,上述hashmap的key是num[i],也就是数组的真实值,value是对应的下标,
num[i]%hashmap.length,就会找到存储的位置,所以hashmap查找速度为1,加上遍历也就整体为O(N)
本来想用C,但是C的hashmap要自己写,
说一下思路吧,先定义一个结构体
一个Data,包含key,value
HashMap节点,
HashMapTable,
Const static int INT_MIN=-32768 typedef struct{ int key; int value; }Datatype; typedef struct{ Datatype data; struct HashNode *next; }HashNode; typedef struct{ int size; HashNode *table; }HashMap,*hashMap;
再写table的创建函数
把key输入进去,然后赋值value,如果该位置被占用,就分配一个空间,往后
//f1_createHashMap //将给定的整形数组构建为HashMap,size为数组长度 HashMap *CreateHashMap(int *nums,int size){ //分配内存空间 HashMap *hashmap=(HashMap*)malloc(sizeof(HashMap)); hashmap->size=2*size; //hash表分配空间 hashmap->table=(HashNode *)malloc(sizeof(HashNode)*hashmap->size); //初始化 int j=0; for(j=0;j<hashmap->size;j++){ hashmap->table[j].data.val=INT_MIN; hashmap->table[j].next=NULL; } int i=0; //建立HashMap while(i<size){ //根据数组元素的值计算其在hashMap中的位置 int pos=abs(nums[i])%hashmap->size; //判断是否冲突 if(hashmap->table[pos].data.val==INT_MIN){ //不冲突 //把元素在数组中的索引作为key hashmap->table[pos].data.key=i; //把元素值作为value hashmap->table[pos].data.val=nums[i]; } //冲突 else{ //给当前元素分配一个结点,并为结点复制 HashNode *lnode=(HashNode*)malloc(sizeof(HashNode)),*hashnode; lnode->data.key=i; lnode->data.val=nums[i]; lnode->next=NULL; //从冲突位置开始,遍历链表 hashnode=&(hashmap->table[pos]); while(hashnode->next!=NULL){ hashnode=hashnode->next; } //将当前结点连接到链表尾部 hashnode->next=lnode; } //处理下一个元素 i++; } //处理完成,返回HashMap return hashmap; }