线性DP-前缀和

本文讨论了如何在给定的二进制字符串中找到最长连续1或0的子串,以及如何在一个整数数组中查找满足特定条件的中心下标。通过遍历和计算前缀和,实现高效算法解决这两个问题。
摘要由CSDN通过智能技术生成

哪种连续子字符串更长

思路

我们遍历输入字符串s中的每个字符。对于每个字符,我们检查它是1还是0,并相应地更新currentLength1currentLength0。当我们遇到一个1时,我们增加currentLength1的值,并将currentLength0重置为0,因为我们正在构建一个连续的1的子字符串。类似地,当我们遇到一个0时,我们增加currentLength0的值,并将currentLength1重置为0

在每次更新currentLength1currentLength0之后,我们还使用Math.max函数来更新maxLength1maxLength0,以确保我们总是记录最长的连续子字符串长度。

最后,我们比较maxLength1maxLength0的值,如果maxLength1大于maxLength0,则返回true,否则返回false

代码

public class 子字符串 {
	public static boolean checkBinaryString(String s) {
		int maxLength1 = 0;
		int maxLength0 = 0 ;
		int currentLength1 = 0;
		int currentLength0 = 0;
		
		for(char c:s.toCharArray()) {
			if(c=='1') {
				currentLength1++;
				currentLength0=0;//遇到1时 重置0的连续的长度
			}else {
				currentLength0++;
				currentLength1=0;//遇到0时重置1的连续的长度
			}
		    //更新最长连续的子字符串的长度
			maxLength1=Math.max(maxLength1, currentLength1);
			maxLength0=Math.max(maxLength0, currentLength0);	
		}

		return maxLength1 > maxLength0;
		
	}
	public static void main(String[] args) {
		String s="110100010";
		System.out.println(checkBinaryString(s));
		
		String v="1101";
		System.out.println(checkBinaryString(v));
		
	}
	

}

知识

for(char c : s.toCharArray())

在Java中,for(char c : s.toCharArray()) 是一个增强型for循环(也称为"foreach"循环),它允许你遍历数组或集合的每个元素而不需要显式地使用索引或迭代器。在这个特定的例子中,s.toCharArray()方法将字符串s转换成一个字符数组,然后增强型for循环遍历这个数组,每次迭代都将数组中的一个字符赋值给变量c

这里是for(char c : s.toCharArray())循环的详细步骤:

  1. s.toCharArray():这个方法调用将字符串s转换成一个新的字符数组。例如,如果s"1101",那么s.toCharArray()将返回一个包含字符'1''1''0', 和'1'的字符数组。

  2. for(char c : ...):这是增强型for循环的语法。对于字符数组中的每个元素(在这个例子中是每个字符),循环体将执行一次。

    • 在每次迭代中,数组中的一个字符会被赋值给变量c
    • 循环体会执行,通常是执行一些操作,比如更新计数器、检查条件等。
    • 当数组中的所有元素都被访问过后,循环结束。

在你的checkBinaryString方法中,增强型for循环用于遍历字符串s中的每个字符。在循环体内,你检查当前字符是'1'还是'0',并相应地更新currentLength1currentLength0变量来跟踪当前正在构建的连续1或连续0的子字符串的长度。

寻找数组的中心下标

思路

拿到题目后思考:数组的下标是从0开始的,且是中心下标的那个对应元素值不会被 + 到左右任何一侧,这个元素相当于一个分界线。

这个CenterIndexFinder类包含了一个findCenterIndex方法,该方法用于查找一个整数数组的中心下标。中心下标是数组的一个下标,其左侧所有元素之和等于右侧所有元素之和。如果没有中心下标,则返回-1。

下面是对findCenterIndex方法的详细解释:

  1. 参数
    • nums:输入的整数数组。
  2. 变量初始化
    • n:数组nums的长度。
    • prefixSum:一个长度为n + 1的数组,用于存储前缀和。前缀和是一种快速计算数组某个区间和的技术。prefixSum[i]表示nums数组中前i个元素的和。
    • leftSum:一个变量,用于存储当前下标左侧的元素之和。
  3. 计算前缀和
    • 通过一个循环,计算nums数组的前缀和,并存储在prefixSum数组中。循环结束时,prefixSum[i]将包含nums数组中前i个元素的和。
  4. 寻找中心下标
    • 再次遍历nums数组,对于每个下标i
      • 计算右侧元素之和rightSum。由于prefixSum[n]表示整个数组的和,prefixSum[i + 1]表示下标i右侧(不包括i)的元素之和,因此rightSum可以通过prefixSum[n] - prefixSum[i + 1]得到。
      • 比较leftSumrightSum。如果它们相等,说明找到了中心下标,返回当前下标i
      • 更新leftSum,将其加上当前元素nums[i],为下一个下标的检查做准备。
  5. 返回结果
    • 如果遍历完整个数组都没有找到中心下标,则返回-1。
  6. 主函数main
    • 定义一个示例数组nums
    • 调用findCenterIndex方法,并将结果存储在centerIndex变量中。
    • 打印结果。

对于给定的示例数组{1, 7, 3, 6, 5, 6},输出将是Center index: 3,因为下标3(对应元素6)左侧的元素和(1 + 7 + 3 = 11)等于右侧的元素和(5 + 6 = 11)。

代码

public class 中心下标 {

	public static  int findCenterIndex(int[] nums) {
		int n=nums.length;
		int [] prefixSum = new int[n+1];
		for(int i=0;i<n;i++) {
			prefixSum[i+1]=prefixSum[i]+nums[i];
		}
		
		int leftSum = 0; //左侧元素之和
		
		//遍历数组,计算每个下标处的左侧元素之和		
		for(int i=0;i<n;i++) {
			int rightSum = prefixSum[n]-prefixSum[i+1];

			//检查左右元素之和是否相等
			if(leftSum == rightSum) {
				return i;
			}
			//更新左侧元素之和,为下一个下标的检查做准备
			leftSum +=nums[i];
		}
		//如果没找到,返回-1
		return -1;
		
	}
	public static void main(String[] args) {
		int [] nums= {1,7,3,6,5,6};
		int centerIndex =findCenterIndex(nums);
		System.out.println(centerIndex);
	}
	
}
  • 20
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值