给定一个int数组A及其大小n以及需查找的和sum,请返回数组中两数之和为sum的整数对的个数。保证数组大小小于等于3000。
测试样例:
[1,2,3,4,5],5,6
返回:2
//虽然很low ,但代码看起简单,哈哈 class FindPair { public: int countPairs(vector<int> A, int n, int sum) { int i,j,count=0; for( i=0;i<n;i++) { for(j=0;j<n;j++) { if(i==j)continue; if(A[i]+A[j]==sum)count++; } } return count/2; } };
class FindPair { public: int countPairs(vector A, int n, int sum) { // write code here sort(A.begin(),A.end()); int low = 0,high = n-1; int count = 0; while(low < high) { if(A[low]+A[high] < sum) low++; else if(A[low]+A[high] > sum) high--; else { if(A[low] == A[high]) { count += (high-low+1)*(high-low)/2; break; }else{ int high_num=1,low_num=1; while(low <high-1 && A[high]==A[high-1]) { high_num++; high--; } while(low+1<high && A[low]==A[low+1]) { low_num++; low++; } low++; high--; count += high_num*low_num; } } } return count; } };
public int countPairs(int[] A, int n, int sum) { // write code here Arrays.sort(A); int k = -1; for(int i = n-1; i>=0; i--){ if(A[i] < sum){ k = i; break; } } if(k == -1){ return 0; } int count = 0; for(int i =0 ;i< k; i++){ for(int j = i+1; j<=k ;j++){ if(A[i] + A[j] == sum){ count++; } } } return count; }
// map // 时间复杂度O(n) // 注意 两个数相等的情况 class FindPair { public: int countPairs(vector<int> A, int n, int sum) { // write code here map<int, int> ma; int count = 0; for (int i = 0; i < n; ++i) { ++ma[A[i]]; if (2 * A[i] == sum) { if (ma[A[i]] > 0) { count += ma[A[i]] - 1; } } else { count += ma[sum - A[i]]; } } return count; } };
运行时间:6ms
占用内存:620k
class FindPair { public: int countPairs(vector<int> A, int n, int sum) { map<int,int> M; for(int i=0;i<n;i++) M[A[i]]++; int cnt = 0; for(int i=0;i<n;i++){ int t = sum - A[i]; if(M[A[i]]!=0){ if(A[i]==t) cnt += M[t]*(M[t]-1)/2; else if(M.find(t)!=M.end() && M[t]!=0) cnt += M[A[i]]*M[t]; M[A[i]] = M[t] = 0; } } return cnt; } };
要保证数组下标i、j不相等哦
import java.util.*;
public class FindPair {
public int countPairs(int[] a, int n, int sum) {
// write code here
int count = 0;
for (int i = 0; i < n - 1; i++) {
for (int j = i + 1; j < n; j++) {
int temp = a[i] + a[j];
if (i != j) {
if (temp == sum) {
count++;
}
}
}
}
return count;
}
}
import java.util.*; public class FindPair { public int countPairs(int[] A, int n, int sum) { HashMap<Integer,Integer> map=new HashMap<>(); int count=0; for(int temp:A){ count+=map.getOrDefault(sum-temp,0); map.put(temp,map.getOrDefault(temp,0)+1); } return count; } }
python O(n) solution
from collections import defaultdict
class FindPair:
def countPairs(self, A, n, tsum):
dd=defaultdict(int)
for i in A:dd[i]+=1
setA=list(set(A))
setA.sort()
start, end = 0, len(set(A))-1
res = 0
while start < end:
if setA[start] + setA[end] < tsum:
start += 1
elif setA[start] + setA[end] > tsum:
end -= 1
else:
res += dd[setA[start]]*dd[setA[end]]
start+=1
end-=1
if setA[start]*2==tsum:
res+=dd[setA[start]]*(dd[setA[start]]-1)//2
return res
import java.util.*; /* 思路:可以将数组排序,然后左右两边两个指针往里缩(相加之和小于sum,左进,大于sum,右缩),直到两个指针相同为止 但是这里面有一个问题,就是还要额外计算相同数字可以组成不同的配对方式(这部分参考了大佬的写法) 还有一种用hashmap的方法其实也很好用,只是开始没有想到 haiy */ public class FindPair { public int countPairs(int[] A, int n, int sum) { int start =0,end=n-1,count=0; Arrays.sort(A); while(start<end){ if(A[start]+A[end]<sum) start++; else if(A[start]+A[end]==sum){ if(A[start]==A[end]){ int t=end -start+1; count+=(t*(t-1)/2); break; } else { int left=start+1,right=end-1; int countleft=1,countright=1; while(A[left]==A[start]){ countleft++; left++; } while(A[right]==A[end]){ countright++; right--; } count+=(countleft*countright); start=left; end =right; } } else end--; } return count; } } 运行时间:163ms 占用内存:13580k
哈希表,O(n) #include<unordered_map> class FindPair { public: int countPairs(vector<int> A, int n, int sum) { unordered_map<int, int> count; int res = 0; for (auto& i : A) ++count[i]; if ((sum & 1) == 0 && count.find(sum >> 1) != count.end()) { res += (count[sum >> 1] * (count[sum >> 1] - 1)) >> 1; count.erase(sum >> 1); } for (auto& pr : count) { if (pr.first < sum - pr.first && count.find(sum - pr.first) != count.end()) res += pr.second * count[sum - pr.first]; } return res; } };
public int countPairs(int[] A, int n, int sum) { HashMap<Integer, Integer> map = new HashMap<Integer, Integer>(n); int count = 0; for (int i = 0; i < n; i++) { if(map.containsKey(sum-A[i])){ count +=map.get(sum-A[i]); } if(map.containsKey(A[i])){ map.put(A[i], map.get(A[i])+1); }else { map.put(A[i], 1); } } return count; }
//O(n)解法 import java.util.*; public class FindPair { public int countPairs(int[] A, int n, int sum) { // write code here HashMap<Integer, Integer> hashMap = new HashMap<>(); int count = 0; for (int i = 0; i < n; i++) { count += getTimes(hashMap, sum - A[i]); hashMap.put(A[i], getTimes(hashMap, A[i]) + 1); } return count; } private Integer getTimes(HashMap<Integer, Integer> hashMap, Integer word) { Integer time = hashMap.get(word); return time == null ? 0 : time; } }
//我是yishuihan,再不努力,我就找不到工作了!只能喝西北风了; int countPairs(vector<int> A, int n, int sum) { // write code here if(n<=1) return 0; int count=0; map<int,int> mymap; for(int i=0;i<n;i++) mymap[A[i]]++; map<int,int>::iterator it; for(it=mymap.begin();it!=mymap.end();it++) { map<int,int>::iterator temp=mymap.find(sum-(it->first)); //假如找到了,并且不是同一个元素,如2(有3个)和4(有5个),sum=6。那么结果应该有3*5=15对; if(temp!=mymap.end() && temp!=it) { count+=(it->second)*(temp->second); it->second=temp->second=0; } else if(temp!=mymap.end())//找到的是同一个元素,如3和3,sum=6.结果应该有3*(3-1)/2对; { count+=(it->second)*((it->second)-1)/2; it->second=0; } } return count; } /*暴力法,有点low,时间复杂度0(n^2),空间复杂度0(1) int countPairs(vector<int> A, int n, int sum) { // write code here if(n<=1) return 0; int count=0; for(int i=0;i<n-1;i++) { for(int j=i+1;j<n;j++) { if(A[i]+A[j]==sum) count++; } } return count; } */
# -*- coding:utf-8 -*- class FindPair: def countPairs(self, A, n, tsum): if n < 2: return 0 A.sort() count = 0 i = 0 j = n - 1 while i < j: if A[i] + A[j] == tsum: if A[i] == A[j]: x = j - i + 1 count += (x*(x-1)/2) break else: samei = 1 samej = 1 while i < j and A[i] == A[i + 1]: samei += 1 i += 1 while i < j and A[j] == A[j - 1]: samej += 1 j -= 1 count += samei * samej i += 1 j -= 1 elif A[i] + A[j] > tsum: j -= 1 else: i += 1 return count
//数组排序后,前后两个指针向中间夹击,若找到符合要求的两个数,需要继续向中间夹,看重复的 //数有多少,需要相乘才是正确的数量;最后如果到中间符合要求,但end和start所指的数相同,则///不是左右数目相乘,而是C(n,2) import java.util.*; public class FindPair { public int countPairs(int[] A, int n, int sum) { int[] B = A.clone(); Arrays.sort(B); int end = n - 1, start = 0, count = 0; while(end > start){ int left = B[start], right = B[end]; if(left + right > sum){ end --; continue; } else if(left + right < sum){ start ++; continue; } else { int countLeft = 1, countRight = 1; if(left == right){ while(B[++start] == left) countLeft ++; count += (countLeft * (countLeft - 1)) >> 1; break; } while(B[++start] == left) countLeft ++; while(B[--end] == right) countRight ++; count += countLeft * countRight; } } return count; } }
import java.util.*; public class FindPair { public int countPairs(int[] A, int n, int sum) { HashMap<Integer, Integer> hashMap = new HashMap<>(); int count = 0; for (int i=0; i<n; i++) { count += getCount(hashMap, sum - A[i]); hashMap.put(A[i], getCount(hashMap, A[i]) + 1); } return count; } private Integer getCount(HashMap<Integer, Integer> hashMap, Integer word){ Integer get = hashMap.get(word); return get == null ? 0 : get; } }