算法-解题方法-前缀和

前缀和解释和简单例题

1248. 统计「优美子数组」

import java.util.*;
class Solution {
    public int numberOfSubarrays(int[] nums, int k) {
        //前缀和+HashMap优化的方法
        int odd=0;//存储奇数的个数 ,前缀和
        int ret=0;//存储最终结果
        int arr[]=new int[nums.length+1];//arr[i]表示前缀和为i的次数
        arr[0]=1;//表示不选任何数的话,前缀和就为0,所以前缀和为0的一定有一个
        for(int i=0;i<nums.length;i++){
            odd+=nums[i]&1;
            arr[odd]++;
            if(odd-k>=0){
                ret+=arr[odd-k];
            }
        }
        return ret;

        /* 计算的方法
        int ret=0;
        if(nums.length==0) return 0;
        ArrayList<Integer> list=new ArrayList<>();
        for(int i=0;i<nums.length;i++){
            if((nums[i]&1)==1)
                list.add(i);
        }
        if(list.size()<k) return 0;
        for(int i=0;i<list.size();i++){
            int left=1;
            int right=1;
            if(i-1<0) left=list.get(i)+1;
            else  left=list.get(i)-list.get(i-1);
            boolean flag=false;
            if(i+k>=list.size()){
            	right=nums.length-list.get(i+k-1);
            	flag=true;
            }else{
            	right=list.get(i+k)-list.get(i+k-1);
            }
            if(i+k-1<list.size()) 
                ret+=left*right;
            if (flag) break;
        }
        return ret;*/
    }
}

1371. 每个元音包含偶数次的最长子字符串
过程:考虑使用前缀和计算前面的字符串的奇偶数量。

public int findTheLongestSubstring(String s) {
        char[] c=s.toCharArray();
        int arr[]=new int[32]; //31=(11111)2 key是状态 value是最小下标
        //保存的是 c[i+1]之前(不包括i+1)的奇偶数状态
        for(int i=0;i<arr.length;i++){
            arr[i]=-1;
        }
        int ret=0;
        arr[0]=0;//状态00000的下标是-1+1=0
        int status=0;//原始状态
        for(int i=0;i<c.length;i++){
            //计算此时的10110(aeiou) 状态 ,0表示偶数,1表示奇数
            switch(c[i]){
                case('a'):
                    status=status^(1<<4);//异或相同为0,不同为1;如果原来位置为1,1^1为0,表示由奇数变为偶数
                    break;
                case('e'):
                    status=status^(1<<3);
                    break;
                case('i'):
                    status=status^(1<<2);
                    break;
                case('o'):
                    status=status^(1<<1);
                    break;
                case('u'):
                    status=status^(1);
                    break;
                default: 
                    break;
            }
            if(arr[status]==-1){//如果原来位置没有值
                arr[status]=i+1;
            }else{//如果有,则找到出现偶数次
            	ret=Math.max(ret, i+1-arr[status]);
            }
        }
        return ret;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值