LeetCode 1 Two Sum
来源:互联网 发布:口才训练软件下载 编辑:程序博客网 时间:2024/04/26 13:53
题目
分析
看完题目首先可以考虑直接暴力破解,不过O(n*2)的时间复杂度会超时,需要降低时间复杂度。
1.先进行一个快排,两个指针分别指向首(i)尾(j),若和大于要求值则 j--,否则i++
2.先进行一个快排,再在数组中通过二分查找另一个数。
题解
1.
void swap(int *x, int *y){ int temp; temp = *x; *x = *y; *y = temp; return;}
void sort(int arr[],int ind[],int left,int right){ if(left>right) return; int i=left; int j=right; int mid=(left+right)/2; swap(&arr[mid],&arr[left]); swap(&ind[mid],&ind[left]); int temp=arr[left]; while(i!=j) { while(arr[j]>=temp && i<j) j--; while(arr[i]<=temp && i<j) i++; if(i<j) { swap(&arr[i],&arr[j]); swap(&ind[i],&ind[j]); } } swap(&arr[i],&arr[left]); swap(&ind[i],&ind[left]); sort(arr,ind,left,i-1); sort(arr,ind,i+1,right); }
另外一个数组是为了在交换的时候将下标号也跟着交换。
int *twoSum(int numbers[], int n, int target) { int *a=(int *)malloc(2*sizeof(int)); int *index=(int *)malloc(n*sizeof(int)); for(int i=0;i<n;i++) index[i]=i+1; a[0]=a[1]=-1; sort(numbers,index,0,n-1); int i=0; int j=n-1; while (i!=j) { if(numbers[i]+numbers[j]==target) { if(index[i]>index[j]) { a[0]=index[j]; a[1]=index[i]; } else { a[0]=index[i]; a[1]=index[j]; } break; } else if(numbers[i]+numbers[j]<target) i++; else j--; } return a;}
2.
int search(int arr[],int value,int left,int right){ if(left>right) return -1; int mid=(left+right)/2; if(arr[mid]==value) return mid; else if (arr[mid]>value) return search(arr,value,left,mid-1); else return search(arr,value,mid+1,right); }
swap函数和sort函数同解1.
int *twoSum(int numbers[], int n, int target) { int *a=(int *)malloc(2*sizeof(int)); int *index=(int *)malloc(n*sizeof(int)); for(int i=0;i<n;i++) index[i]=i+1; a[0]=a[1]=-1; sort(numbers,index,0,n-1); for(int i=0;i<n;i++) { int j=search(numbers,target-numbers[i],i+1,n-1); if(j!=-1) { if(index[i]>index[j]) { a[0]=index[j]; a[1]=index[i]; } else { a[0]=index[i]; a[1]=index[j]; } break; } } return a;}
再说说快排
int mid=(left+right)/2; swap(&arr[mid],&arr[left]); swap(&ind[mid],&ind[left]);
快排里面有这神奇的三句,是因为再没加之前是超时的,错误的例子是一个递增的长序列。
在这个递增的长序列中,不论是以最左边为参照还是以最右边为参照都会全部进行比较,时间复杂度为O(N*2)
这样还是过不去的(如果这样都能过,不如直接写两层for循环)
于是投机的把最中间的值先换到了左边,再也左边为参照,一次全部交换完毕才通过了测试。
不仅能写出算法,还 知道它最适合的情景和最不适合的情景 也是很重要的。
再试试桶排序
int *twoSum(int numbers[], int n, int target) { int *a=(int *)malloc(2*sizeof(int)); int *index=(int *)malloc(40000*sizeof(int)); //定义40000个桶 默认值为-1 for(int i=0;i<40000;i++) index[i]=-1; for(int i=0;i<n;i++) //将元素的索引存在 值+1000 的地桶里 { index[numbers[i]+1000]=i; } int temp,j; for(int j=0;j<n;j++) { temp=index[target-numbers[j]+1000]; // 查找另一个数时,查找该数值+1000的桶里有没有不为-1的排号 if(temp!=-1 && temp!=j) // 不为-1的排号 且与第一个数索引不同 则为另一个值的索引 { if(j>temp) { a[0]=temp+1; a[1]=j+1; } else { a[0]=j+1; a[1]=temp+1; } return a; } } }
加1000是为了使得下标值都为正数
试试C++
class Solution {public: vector<int> twoSum(vector<int> &numbers, int target) { vector<int> results; multimap<int, int> iimmap; for(int i=0; i<numbers.size(); i++){ iimmap.insert(pair<int, int>(numbers[i], i)); } for(int i=0;i<numbers.size();i++) { if(iimmap.count(target-numbers[i])) { int n=iimmap.find(target-numbers[i])->second; if(n<i) { results.push_back(n+1); results.push_back(i+1); return results; } else if(n>i) { results.push_back(i+1); results.push_back(n+1); return results; } } } }};
思路同桶排序一样,不过更简单,不用考虑数组下标为负时需要做的偏移。用到了:
1.multimap的插入,直接插入pair<int,int>类型的数据
2.通过multimap.count(key)来统计是否有key主键存入
3.multimap.find(key)得到指向key的iterator iterator->second获得了key对应的value值,也就是我们需要的索引值。
简单点
class Solution {public: vector<int> twoSum(vector<int> &numbers, int target) { map<int, int> iimmap; vector<int> results; for(int i=0; i<numbers.size(); i++){ if(iimmap.count(target-numbers[i])){ int n=iimmap.find(target-numbers[i])->second; results.push_back(n+1); results.push_back(i+1); return results; } iimmap.insert(pair<int, int>(numbers[i], i)); } return results; }};
用JAVA的Hashmap
public class Solution { public int[] twoSum(int[] numbers, int target) { Map<Integer, Integer> map = new HashMap<>(); for (int i = 0; i < numbers.length; i++) { if (map.containsKey(target - numbers[i])) { return new int[] { map.get(target - numbers[i]) + 1, i + 1 }; } map.put(numbers[i], i); } throw new IllegalArgumentException("No two sum solution"); }}
其实上面的两次for循环只是为了看起来理解更方便,实际上一次for循环就能解决。
0 0
- LeetCode 1 - Two Sum
- leetcode 1 Two Sum
- Leetcode【1】:Two Sum
- [leetcode 1] Two Sum
- 【leetcode-1】Two Sum
- [leetcode 1] Two Sum
- [Leetcode] 1 - Two Sum
- LeetCode (1) Two Sum
- LeetCode 1:《Two Sum》
- LeetCode | #1 Two Sum
- leetcode-1 Two Sum
- Two Sum | LeetCode(1)
- [Leetcode]1Two Sum
- leetcode 1 Two Sum
- leetcode #1 Two Sum
- leetcode 1:Two Sum
- LeetCode 1 Two Sum
- leetcode #1 two sum
- 多线程中的信号机制--sigwait()函数
- Python lambda表达式
- #ifndef #define #endif
- 基数排序
- 遇到g++的最不靠谱报错!
- LeetCode 1 Two Sum
- java学习笔记——1
- vector/array
- 日期工具类
- WIFI芯片调试APP Wif网络精灵
- 考研小助手-Mathematica显示结题步骤
- C++函数参数个数不定
- 调侃《HeadFirst设计模式》之工厂模式(一)
- 计算机视觉领域的一些牛人博客,超有实力的研究机构等的网站链接---个人整理