【问题标题】:Codingbat challenge: sameEnds Stream API SolutionCodingbat 挑战:sameEnds Stream API 解决方案
【发布时间】:2022-06-10 18:09:00
【问题描述】:

鉴于CodingBat的任务sameEnds

如果数组开头和结尾的N 数字组相同,则返回true。例如,对于{5, 6, 45, 99, 13, 5, 6}n=0n=2 的结尾相同,n=1n=3 的结尾为 false。您可以假设n0..nums.length 范围内。

sameEnds([5, 6, 45, 99, 13, 5, 6], 1) → false
sameEnds([5, 6, 45, 99, 13, 5, 6], 2) → true
sameEnds([5, 6, 45, 99, 13, 5, 6], 3) → false

我对这个问题的解决方案通过了绝大多数测试,但不是全部:

public boolean sameEnds(int[] nums, int len) {
  
  if (nums.length >= len * 2) {
    for (int i = 0, j = nums.length - 1 ; i < len && len > 0; i++, j--) {
       if (nums[i] != nums[j]) {
         return false;
       }
    }
  }
  
  return true;
}

我的问题如下:

  1. 可以做些什么来修复我的解决方案?
  2. 是否可以使用 Stream API 解决此任务?

【问题讨论】:

  • 哪些测试用例失败了?
  • 规范不禁止len大于nums.length / 2。起点和终点可以重叠。

标签: java arrays for-loop if-statement java-stream


【解决方案1】:

您可以使用allMatch() 操作以通过流实现它。

此解决方案通过了 CodingBat 上的所有测试用例:

public boolean sameEnds(int[] nums, int len) {
    return java.util.stream.IntStream.range(0, len)
        .allMatch(n -> nums[n] == nums[nums.length - (len - n)]);
}

命令式解决方案的修复可能如下所示:

public boolean sameEnds(int[] nums, int len) {
    for (int i = 0, j = nums.length - 1 - (len - 1); i < len; i++, j++) {
        if (nums[i] != nums[j]) {
            return false;
        }
    }
    return true;
}

我删除了换行 if 条件,因为当 nums.length &gt;= len * 2 被评估为 false 这意味着需要比较的 子数组 重叠,但这并不意味着这些 子数组是相等的。

条件len &gt; 0 是多余的,因为它保证在[0,nums.length] 范围内。

变量j 表示尾部子数组 中的位置已初始化为nums.length - 1 - (len - 1) - 最后一个有效索引减去子数组的 长度。而for循环的所谓增量语句j--改为j++

【讨论】:

    【解决方案2】:

    如果您使用的是 Java 9 或更高版本,则可以使用内置方法 Arrays.equals

    public boolean sameEnds(int[] nums, int len) {
        return Arrays.equals(nums, 0, len, nums, nums.length - len, nums.length);
    }
    

    【讨论】: