算法题解----leetcode.1865找出和为指定值的下标对
题目描述:
给你两个整数数组 nums1 和 nums2 ,请你实现一个支持下述两类查询的数据结构:
累加 ,将一个正整数加到 nums2 中指定下标对应元素上。
计数 ,统计满足 nums1[i] + nums2[j] 等于指定值的下标对 (i, j) 数目(0 <= i < nums1.length 且 0 <= j < nums2.length)。
实现 FindSumPairs 类:
FindSumPairs(int[] nums1, int[] nums2) 使用整数数组 nums1 和 nums2 初始化 FindSumPairs 对象。
void add(int index, int val) 将 val 加到 nums2[index] 上,即,执行 nums2[index] += val 。
int count(int tot) 返回满足 nums1[i] + nums2[j] == tot 的下标对 (i, j) 数目。
示例:
输入: ["FindSumPairs", "count", "add", "count", "count", "add", "add", "count"] [[[1, 1, 2, 2, 2, 3], [1, 4, 5, 2, 5, 4]], [7], [3, 2], [8], [4], [0, 1], [1, 1], [7]] 输出: [null, 8, null, 2, 1, null, null, 11] 解释: FindSumPairs findSumPairs = new FindSumPairs([1, 1, 2, 2, 2, 3], [1, 4, 5, 2, 5, 4]); findSumPairs.count(7); // 返回 8 ; 下标对 (2,2), (3,2), (4,2), (2,4), (3,4), (4,4) 满足 2 + 5 = 7 ,下标对 (5,1), (5,5) 满足 3 + 4 = 7 findSumPairs.add(3, 2); // 此时 nums2 = [1,4,5,4,5,4] findSumPairs.count(8); // 返回 2 ;下标对 (5,2), (5,4) 满足 3 + 5 = 8 findSumPairs.count(4); // 返回 1 ;下标对 (5,0) 满足 3 + 1 = 4 findSumPairs.add(0, 1); // 此时 nums2 = [2,4,5,4,5,4] findSumPairs.add(1, 1); // 此时 nums2 = [2,5,5,4,5,4] findSumPairs.count(7); // 返回 11 ;下标对 (2,1), (2,2), (2,4), (3,1), (3,2), (3,4), (4,1), (4,2), (4,4) 满足 2 + 5 = 7 ,下标对 (5,3), (5,5) 满足 3 + 4 = 7
这题我一开始原本想用双指针做的,结果发现出现了我无法解决的错误,这种思路也许是对的,但是好像出了点内存的问题
我也不知道这应该怎么去修改,于是只好放弃了双指针算法,之后我又算了一下时间复杂度好像也不太行,
因为我每次要sort一下再用双指针,count函数时间复杂度就是 O( nlogn + n + m+ mlogm)
这个函数大概调用1000次,而m最大可以取10^5,所以应该会超时,看一下我的count代码
vector<int> nums1;
vector<int> nums2;
int len1;
int len2;
int count(int tot) { int cnt = 0; sort(nums1.begin(),nums1.end()); sort(nums2.begin(),nums2.end()); for(int i=0,j=len2-1;i<len1;) { int l = i; int mul = 0; while(l<len1 && nums1[l]==nums1[i]) mul++,l++; while(j>=0 && nums1[i]+nums2[j]>tot) j--; if(nums1[i]+nums2[j]==tot) { int k =j; while(k>=0 && nums2[k]==nums2[j]) { cnt+=mul; k--; } j = k; } i = l; } return cnt; }
这个函数功能应该是没问题的。
那么我之后使用什么方法过的呢?
我开了一个map,这题就变得贼简单
1 class FindSumPairs { 2 public: 3 int len1 = 0; 4 int len2 = 0; 5 vector<int> nums1; 6 vector<int> nums2; 7 map<int,int> mp; 8 FindSumPairs(vector<int>& nums1, vector<int>& nums2) { 9 this->len1 = nums1.size(); 10 this->len2 = nums2.size(); 11 this->nums1 = nums1; 12 this->nums2 = nums2; 13 for(auto i :nums2) 14 mp[i]++; 15 } 16 17 void add(int index, int val) { 18 mp[nums2[index]+val]++; 19 mp[nums2[index]]--; 20 nums2[index] += val; 21 } 22 23 int count(int tot) { 24 int cnt = 0; 25 for(auto i : nums1) 26 cnt+=mp[tot-i]; 27 return cnt; 28 29 } 30 };
一共就只有30行代码。。。。。
思路也很简单.......
脑子抽了……