算法题解----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行代码。。。。。

思路也很简单.......

脑子抽了……

 

posted @ 2021-08-24 23:57  Apak陈柏宇  阅读(81)  评论(0编辑  收藏  举报