牛牛有两个长度为的数组,牛牛希望统计有多少数对满足:
1,
2,
class Solution { public: /** * 计算有多少对符合条件的数对 * @param a int整型vector 数组a * @param b int整型vector 数组b * @return int整型 */ int countLR(vector<int>& a, vector<int>& b) { int n = a.size(), cnt = 0; vector<int> c(n, 0); c[0] = a[0]; for(int i=1;i<n;i++) c[i] = c[i-1] + a[i]; for(int l=0;l<n;l++) for(int r=l;r<n;r++){ if(l==0 && (c[r] == b[l]+b[r])) cnt++; else if(l!=0 && (c[r]-c[l-1] == b[l]+b[r])) cnt++; } return cnt; } };
int countLR(vector<int>& a, vector<int>& b) { int n = a.size(); vector<int> tmp = vector<int>(n + 1, 0); for(int i = 1; i <= n; i++) tmp[i] += (tmp[i-1] + a[i-1]); int res = 0; for(int i = 1; i <= n; i++) for(int j = i - 1; j < n; j++) if(tmp[j+1] - tmp[i-1] == b[i-1] + b[j]) res++; return res; }
对a数组统计前缀和,假设当前区间为[l,r],根据题意有pre[r + 1] - pre[l] == bl + br,变换等式为pre[r + 1] - br == bl + pre[l];因此我们倒序遍历b数组,枚举其左边界,同时统计pre[r + 1] - br的个数即可
import collections class Solution: def countLR(self , a , b ): # write code here pre = [0] for i in range(len(a)): pre.append(pre[-1] + a[i]) v = collections.defaultdict(int) ans = 0 for i in range(len(b) - 1,-1,-1): v[pre[i + 1] - b[i]] += 1 cur = b[i] + pre[i] ans += v[cur] return ans
# # 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 # # 计算有多少对符合条件的数对 # @param a int整型一维数组 数组a # @param b int整型一维数组 数组b # @return int整型 # class Solution: def countLR(self, a, b): size = len(a) count = 0 a_sums = [a[0]] for i in range(1, size): a_sums.append(a_sums[i - 1] + a[i]) for l in range(size): for r in range(l, size): if r == l: if a[r] == b[r] + b[l]: count = count + 1 else: if a_sums[r] - a_sums[l] + a[l] == b[r] + b[l]: count = count + 1 return count
class Solution: def countLR(self , a , b ): # write code here n = len(a) res = 0 s = [] s.append(a[0]) for i in range(1, n): s.append(s[i-1] + a[i]) for l in range(n): for r in range(l, n): if s[r] - s[l] + a[l] == b[l] + b[r]: res += 1 return res用前缀和数组把时间降到n2还是不行
import java.util.*; public class Solution { /** * 计算有多少对符合条件的数对 * @param a int整型一维数组 数组a * @param b int整型一维数组 数组b * @return int整型 */ public int countLR (int[] a, int[] b) { int count = 0; for(int i = 0;i < a.length;i++){ int less = a[i]-2*b[i]; if(less == 0){ count++; } for(int j = i+1;j < a.length;j++){ less += a[j]+ b[j-1]-b[j]; if(less == 0){ count++; } } } return count; } }
public int countLR (int[] a, int[] b) { int[] sum = new int[a.length]; sum[0] = a[0]; for (int i = 1; i < a.length; i++) { sum[i] = sum[i - 1] + a[i]; } int res = 0; for (int l = 0; l < a.length; l++) { for (int r = l; r < a.length; r++) { int curSum = sum[r] - (l - 1 >= 0 ? sum[l -1] : 0); int bSum = b[l] + b[r]; if (curSum == bSum) res++; } } return res; 使用一个求和数组优化时间复杂度。
func countLR( a []int , b []int ) int { if len(a)==0||len(b)==0||len(a)!=len(b){ return 0 } //计算前缀和:sumA[0]=a[0],sumA[1]=a[0]+a[1] ... sumA:=make([]int,len(a)) temp:=0 for k,v:=range a{ temp+=v sumA[k]=temp } result:=0 target := map[int]int{} //由条件1可知:l<=r //由条件2可知: a[l]+a[l+1]+...a[r]=b[l]+b[r] //也即是:sumA[r]-sumA[l]+a[l]=b[l]+b[r] //移项得:sumA[r]-b[r]=b[l]+sumA[l]-a[l] //使用map:target保存所有等式右边的“b[l]+sumA[l]-a[l]”计算结果,以等式右边的值作为k,结果出现的次数作为v。 //计算等式左边的“sumA[r]-b[r]”值,判断该值在map :target中是否作为k出现过出现过即表示存在等式成立的情况。 //因为l<=r,所以讲循环变量l和r可以统一为k,放入同一个for循环。也即是计算等式左边并判断存在性的时机一定在计算等式右边的时机之后或者同时,绝不会在之前。 for k:=range a{ target[sumA[k]+b[k]-a[k]]+=1 if t,ok:=target[sumA[k]-b[k]];ok{ result+=t } } return result } //此题记录中间结果sumA记录前缀和,使用target记录计算过的值避免重复计算。使得三重循环降低为两次循环。 //时间复杂度从n^3降低到n。空间复杂度从1增加到n。典型的以空间换时间思路。
import java.util.*; public class Solution { /** * 计算有多少对符合条件的数对 * @param a int整型一维数组 数组a * @param b int整型一维数组 数组b * @return int整型 */ public int countLR (int[] a, int[] b) { // write code here int suma = 0; int sumb = 0; int count = 0; for (int L = 0; L < a.length; L++) { for (int R = L; R < a.length; R++) { sumb = b[L] + b[R]; suma = suma + a[R]; if(suma == sumb) { count++; } } suma = 0;// 记得在每次L变化的时候,对suma进行置零 sumb = 0; } return count; } }
class Solution: def countLR(self, a, b): n = len(a) ct = 0 suml = [i for i in range(n + 1)] # left = 0 suml[0] = 0 for r in range(1, n + 1): suml[r] = suml[r - 1] + a[r - 1] for l in range(0, n): for r in range(0, l + 1): if suml[l+1] - suml[r] == b[r] + b[l]: ct += 1 return ctPython 的两个loop,只通过45%。求大神帮看看。
class Solution { public: /** * 计算有多少对符合条件的数对 * @param a int整型vector 数组a * @param b int整型vector 数组b * @return int整型 */ int countLR(vector<int>& a, vector<int>& b) { int len = a.size(); int res = 0; for (int l = 0; l < len; l++) { int sum_l=0; int sum_r = 0; sum_l += a[l]; for (int r = l; r < len; r++) { sum_r += a[r]; if (sum_l - a[l] + b[l] == sum_r - b[r]) res++; } } return res; } };
假设我们已经求出了前缀和,对于下标[i,j]而言,要想符合题目中的数对:
需要满足:
pre[j+1]-pre[i]=b[i]+b[j]
移项
pre[j+1]-b[j]=pre[i]+b[i]
class Solution { public: /** * 计算有多少对符合条件的数对 * @param a int整型vector 数组a * @param b int整型vector 数组b * @return long长整型 */ long long countLR(vector<int>& a, vector<int>& b) { // write code here long long last = 0,ret = 0; unordered_map<int, int> p = { {0,0} }; for (int i = 0; i < a.size(); i++) { p[last + b[i]]++; last += a[i]; if (p.count(last - b[i])) ret += p[last - b[i]]; } return ret; } };
import java.util.*; public class Solution { /** * 计算有多少对符合条件的数对 * @param a int整型一维数组 数组a * @param b int整型一维数组 数组b * @return int整型 */ public int countLR (int[] a, int[] b) { // write code here int result = 0; for (int i = 0; i < a.length; ++i) { int sum = 0; for (int j = i; j < a.length; ++j) { sum += a[j]; if (sum == b[i] + b[j]) { result++; } } } return result; } }