自学内容网 自学内容网

【刷题7】寻找数组的中心下标、和为k的子数组、和可被k整除的子数组

一、寻找数组的中心下标

题目:
在这里插入图片描述

思路:前缀和思想
在这里插入图片描述

  • 预处理一个前缀和数组和一个后缀和数组,当前指向的元素的值不包括在数组的元素和中;
  • 前缀和数组的公式与后缀和数组的公式(注意:要根据题目要求变化,不能死记公式)
  • 细节处理:f[0]和g[n-1]为了防止越界,提前初始化为0;处理前缀和数组正向遍历原数组,处理后缀和数组反向遍历原数组,都是从第二个元素开始遍历(反向同理)

代码:

class Solution {
public:
    int pivotIndex(vector<int>& nums) {
        int n = nums.size();
        int f[n]; // 前缀和数组
        int g[n]; // 后缀和数组
        f[0] = 0, g[n-1] = 0; // 初始化
        // 处理前缀和数组
        for(int i=1; i<n; i++)
        {
            f[i] = f[i-1] + nums[i-1];
        }
        // 处理后缀和数组
        for(int i=n-2; i>=0; i--)
        {
            g[i] = g[i+1] + nums[i+1];
        }
        // 找出中心下标
        for(int i=0; i<n; i++)
        {
            if(f[i] == g[i]) return i;
        }
        return -1;
    }
};

<除自身以外数组的乘积>根据本题变形

二、和为k的子数组

题目:
在这里插入图片描述
思路:前缀和+哈希表

  • 哈希表,第一个int是前缀和,第二个int是该前缀和出现的次数
  • sum在for循环遍历累加,充当前缀和,实际不需要一个新的数组
  • ret就是返回的个数
  • 前缀和与k之间有两种情况:大于和等于。等于的话sum-k=0,所以hash[0]=1
  • 大于的话,sum = k + (sum-k),也就是说,只要sum-k存在,那么就一定有和为k的子数组。所以遍历的过程中同时找hash[sum-k]的个数是否为0,不为0就加到ret去,加的是hash[sum-k],hash[sum-k]就是个数
  • 判断后再++当前的前缀和次数,即保存数据
  • 为什么不能直接用k?因为是Sum做前缀和,不然谁跟k来作比较,而且就算可以比较,k与sum之间如果不相等可能会漏掉一些数据。只要sum-k出现过就有等于k的。特殊情况等于0的话就前面设置一下
  • hash.count()使用:哈希表中存在该数据就返回1,否则返回0

在这里插入图片描述

代码:

class Solution {
public:
    int subarraySum(vector<int>& nums, int k) {
        int n = nums.size();
        unordered_map<int, int> hash;
        hash[0] = 1;// 整个数组和为k
        int sum = 0;// 变量充当前缀和
        int ret = 0;
        for(auto e:nums)
        {
            sum += e;
            if(hash.count(sum-k)) ret += hash[sum-k];
            hash[sum]++;
        }
        return ret;
    }
};

三、和可被k整除的子数组

题目:
在这里插入图片描述
思路:前缀和+哈希表

  • 大体思路与上一道题一样
  • 同余定理,因为有负数
  • 与上一题最大的区别:上一题,判断哈希表是否存在sum-k,将前缀和sum放入哈希表;本题,判断哈希表是否存在前缀和的余数,将余数放入哈希表

代码:

class Solution {
public:
    int subarraysDivByK(vector<int>& nums, int k) {
        int n = nums.size();
        unordered_map<int, int> hash;
        hash[0] = 1;
        int sum = 0, ret = 0;
        for(auto e:nums)
        {
            sum += e;
            int r = (sum%k+k)%k;//同余定理
            if(hash.count(r)) ret += hash[r];
            hash[r]++;
        }
        return ret;
    }
};

原文地址:https://blog.csdn.net/2301_77459845/article/details/142793724

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!