【问题标题】:Merging Overlapping Intervals with Javascript用 Javascript 合并重叠区间
【发布时间】:2021-09-10 13:09:12
【问题描述】:

所以我正在研究 LeetCode 中的合并重叠区间,我已经能够解决 2/3 的测试用例。说明是:

“给定一个区间数组,其中intervals[i] = [starti, endi],合并所有重叠区间,并返回一个覆盖输入中所有区间的非重叠区间数组。”

前两个测试用例是: 输入:intervals = [[1,3],[2,6],[8,10],[15,18]] 输入:intervals = [[1,4],[4,5]] 我的输出分别是[[1,6],[8,10],[15,18]][[1,5]]。这些都过去了。

还有第三个测试用例,我一生都无法弄清楚为什么预期的输出是这样的。

第三个测试用例: 输入:[[1,4],[2,3]] 预期输出:[[1,4]]

这是我的解决方案:

var merge = function(intervals) {
    // sort
    intervals.sort((a, b) => a[0] - b[0])
    
    let previous = intervals[0];
    let result = [previous];
    
    for(let i = 1; i < intervals.length; i++) {
        let current = intervals[i];
        if(previous[1] >= current[0]) {
            previous[1] = current[1];
        } else {
            result.push(current);
            previous = current;
        }
    }
    return result;
};

我的输出是:[[1,3]],因为4大于2,所以有重叠。

为什么预期的输出是[[1,4]] 对我来说是零意义。任何人都可以对此提供任何见解吗?

【问题讨论】:

  • It makes zero sense to me why the expected output would be [[1,4]] 为什么这对你没有意义?如果您有重叠的区间[1,4][2,3],那么包含这两个区间的结果区间是什么? [1,3] 是否包含两者?
  • @t.niese 嗯好的,我现在意识到我犯了一个常见的错误,即没有完全理解问题的含义。我正在做的合并间隔是合并intervals[0][0]intervals[1][1],而我的解决方案恰好适用于前两个测试用例。所以我想我需要做的是比较 intervals[0][1]intervals[1][1] 并取两者中较大的一个。
  • 是的。您没有想到重叠也可能意味着一个区间完全包含在另一个区间中。你只是在他们插入时想到了案例。

标签: javascript


【解决方案1】:

这不是您所需要的,也不是清晰完整的解决方案:

class Interval {
  constructor(start, end) {
    this.start = start
    this.end = end
  }

  merge(interval2) {
    if (this.isOverlapped(interval2)) {
      let resultStart, resultEnd
      resultStart = this.start <= interval2.start ? this.start : interval2.start
      resultEnd = this.end >= interval2.end ? this.end : interval2.end
      return [new Interval(resultStart, resultEnd)]
    } else {
      return this.start <= interval2.start ? [this, interval2] : [interval2, this]
    }
  }

  isOverlapped(interval2) {
    let i1, i2
    if (this.start <= interval2.start) {
      i1 = this
      i2 = interval2
    } else {
      i1 = interval2
      i2 = this
    }
    return i1.end >= i2.start && i1.start <= i2.end
  }

  get print() {
    return `[${this.start}, ${this.end}]`
  }

  get toArray() {
    return [this.start, this.end]
  }
}

class Intervals {
  constructor() {
    this.collection = []
  }

  add(newInterval) {
    if (this.collection.length === 0) {
      this.collection.push(newInterval)
      return
    }

    let isMerged = false
    this.collection.forEach((existedInterval, index) => {
      if (newInterval.isOverlapped(existedInterval)) {
        this.collection[index] = existedInterval.merge(newInterval)[0]
        isMerged = true
      }
    })
    if (!isMerged) {
      this.collection.push(newInterval)
    }
  }

  get print() {
    return JSON.stringify(this.collection.map((x) => x.toArray))
  }
}

const test = [
  [new Interval(1, 2), new Interval(2, 3), true, [[1, 3]]],
  [new Interval(2, 3), new Interval(1, 2), true, [[1, 3]]],
  [new Interval(2, 4), new Interval(1, 3), true, [[1, 4]]],
  [new Interval(1, 3), new Interval(2, 4), true, [[1, 4]]],
  [new Interval(2, 4), new Interval(1, 5), true, [[1, 5]]],
  [new Interval(1, 2), new Interval(3, 4), false, [[1, 2], [3, 4]]],
  [new Interval(3, 4), new Interval(1, 2), false, [[1, 2], [3, 4]]],
  [new Interval(15, 18), new Interval(15, 18), false, [[15, 18]]],
]

// test is two intervals overlaps
test.forEach((testData) => {
  console.log(`test is overlapped[${testData[0].print}, ${testData[1].print}] - ${testData[0].isOverlapped(testData[1]) == testData[2] ? 'passed' : 'isnt passed'}`)
})

// test two intervals merging
test.forEach((testData) => {
  const result = testData[0].merge(testData[1])
  console.log(`test merging[${testData[0].print}, ${testData[1].print}] => [${result.map((x) => x.print)}] - ${JSON.stringify(result.map((x) => x.toArray)) == JSON.stringify(testData[3]) ? 'passed' : 'isnt passed'}`)
})

const test2 = [
  {
    input: [[1, 3], [2, 6], [8, 10], [15, 18]],
    expectedResult: [[1, 6], [8, 10], [15, 18]]
  },
  {
    input: [[1, 4], [4, 5]],
    expectedResult: [[1, 5]]
  },
  {
    input: [[1, 4], [2, 3]],
    expectedResult: [[1, 4]]
  },
  {
    input: [[1, 3], [5, 8], [2, 6]],
    expectedResult: [[1, 8]]
  },
]

test2.forEach((testData) => {
  const result = new Intervals()
  testData.input.forEach((testInterval) => result.add(new Interval(...testInterval)))
  console.log(result.print)
  console.log(`test merging multiple ${JSON.stringify(testData.input)} => ${JSON.stringify(testData.expectedResult)} - ${JSON.stringify(testData.expectedResult) == result.print ? 'passed' : 'isnt passed'}`)
})

查看最后一次测试。没有通过。

【讨论】:

    猜你喜欢
    • 2015-10-18
    • 2018-08-10
    • 1970-01-01
    • 2011-02-05
    • 1970-01-01
    • 1970-01-01
    • 2019-04-12
    • 1970-01-01
    相关资源
    最近更新 更多