Leetcode-每日一题927. 三等分(双指针)

简介: 题目需要你帮他把这个arr序列分成连续的三段序列,序列是由0、1组成,每段的0、1序列组成的二进制数都要相等。你只需要找到第一段序列与第二段序列的分割点 i, 第二段序列与第三段序列的分割点j。

81136735f2f74bd485c6fcee12bea673.png


题目链接点击跳转


题目意思


题目需要你帮他把这个arr序列分成连续的三段序列,序列是由0、1组成,每段的0、1序列组成的二进制数都要相等。你只需要找到第一段序列与第二段序列的分割点 i, 第二段序列与第三段序列的分割点j。


思路


方法一、双指针


这题目要求我们分成三等分的且二进制数相等序列。


  • 1的个数一定得是能被 3 整除的,否则肯定无法三等分。cnt = 1的个数 / 3
  • 我们先用双指针i、j取前后两部分刚好cnt个1的序列。

。从0开始的startI表示去前置零后的第一段序列的二进制数开头,与我们的第三段序列的二进制数开头进行对比,如果出现不相等则不能三等分,否则 startI就是第一段与第二段序列的分割点i。


。我们确定了i是第一段与第二段序列的分割点后,第二段序列的开头则是从i + 1开始的,需要先得到去掉第二段序列的前置零的二进制数开头 idy,与第一段序列去对比,如果出现不相等则不能三等分,否则 idy就是第二段与第三段序列的分割点j。


代码示例:


func threeEqualParts(arr []int) []int {
    cnt := 0
    //统计1的个数
    for _, v := range arr {
        if v == 1{
            cnt++
        }
    }
    if cnt % 3 != 0{
        return []int{-1, -1}
    }else if cnt == 0{
        //如果没有0怎么分配都行,但是只能输出{0, n - 1}才对
        return []int{0, len(arr) - 1}
    }
    n := cnt / 3
    i := 0
    for x := 0; x < n; i++{
        x += arr[i]
    }
    j := len(arr) - 1
    for x := 0; x < n; j--{
        x += arr[j]
    }
    startI := 0
    for arr[startI] == 0{
        startI++
    }
    idx := startI
    startJ := j + 1
    //确定前后两部分的去前置零的序列长度,并判断是否相等,找到I的位置
    for ; startJ < len(arr); startI, startJ = startI + 1, startJ + 1 {
        if arr[startI] != arr[startJ] {
            return []int{-1, -1}
        }
    }
    //确定了I的位置
    i = startI - 1
    //去掉{I, ?}序列的前导零
    idy := i + 1
    for arr[idy] == 0 {
        idy++
    }
    //确定J的位置
    for ; idx <= i; idx, idy = idx + 1, idy + 1 {
        if arr[idx] != arr[idy] {
            return []int{-1, -1}
        }
    }
    j = idy
    return []int{i, j}
}

66f371833dff4021b3568c91b7c553ce.png



复杂度分析


  • 时间复杂度:O(N + i + j),其中N表示arr序列的长度,遍历一遍数组需要O(N)的时间。i 表示 第一段序列的结尾,找到i需要O(i)的时间。j 表示 第二段序列的结尾,找到j需要O(j)的时间。


  • 空间复杂度:O(1),不需要额外申请空间。
目录
相关文章
|
3月前
|
Python
【Leetcode刷题Python】138. 复制带随机指针的链表
LeetCode上题目“138. 复制带随机指针的链表”的Python解决方案,包括两种方法:一种是在每个节点后复制一个新节点然后再分离出来形成新链表;另一种是构建一个字典来跟踪原始节点与其副本之间的映射关系,从而处理新链表的构建。
20 1
|
5月前
|
索引
力扣每日一题 6/17 枚举+双指针
力扣每日一题 6/17 枚举+双指针
31 1
|
5月前
|
存储 算法 数据可视化
【模拟面试问答】深入解析力扣163题:缺失的区间(线性扫描与双指针法详解)
【模拟面试问答】深入解析力扣163题:缺失的区间(线性扫描与双指针法详解)
|
5月前
|
算法 数据挖掘 Java
深入解析力扣167题:两数之和 II(双指针法详解及模拟面试问答)
深入解析力扣167题:两数之和 II(双指针法详解及模拟面试问答)
|
5月前
|
存储 算法 数据挖掘
【模拟面试问答】力扣165题:比较版本号(逐个比较与双指针法详解及模拟面试问答)
【模拟面试问答】力扣165题:比较版本号(逐个比较与双指针法详解及模拟面试问答)
|
5月前
|
存储 算法 数据可视化
深入解析力扣160题:相交链表的解决方法(哈希表法与双指针法详细图解)
深入解析力扣160题:相交链表的解决方法(哈希表法与双指针法详细图解)
|
6月前
|
算法
[优选算法]——双指针——Leetcode——1089. 复写零
[优选算法]——双指针——Leetcode——1089. 复写零
|
5月前
|
算法
【经典LeetCode算法题目专栏分类】【第7期】快慢指针与链表
【经典LeetCode算法题目专栏分类】【第7期】快慢指针与链表
|
5月前
|
算法 容器
【经典LeetCode算法题目专栏分类】【第1期】左右双指针系列:盛最多水的容器、接雨水、回文子串、三数之和
【经典LeetCode算法题目专栏分类】【第1期】左右双指针系列:盛最多水的容器、接雨水、回文子串、三数之和