算法题:请找出字符串中连续最多的字符,以及次数

题目

  • 如,输入 ‘abbcccddeeee1234’,计算得到:
  • 连续最多的字符是 ‘e’,4次

传统思路

  • 嵌套循环,找出每个字符的连续次数,并记录
  • 看似时间复杂度是O(n^2)
  • 但实际复杂度是O(n),因为有 “跳步”

双指针

  • 定义指针 i 和 j。j 不动,i继续移动
  • 如果 i 和 j 的值一直相等,则 i 继续移动
  • 直到 i 和 j 的值不相等,记录处理,让 j 追上 i
/**
 * @description 找出字符串中连续最多的字符,以及次数
 * @author lsr
 */

interface IRes {
  char: string
  length: number
}

/**
 * 找出字符串中连续最多的字符,以及次数 - 嵌套循环
 * @param str
 * @returns
 */
export function findContinuousChar1(str: string): IRes {
  const res: IRes = {
    char: '',
    length: 0
  }

  const length = str.length
  if (length === 0) return res

  // 临时记录连续字符长度
  let tempLength = 0

  // O(n)
  for (let i = 0; i < length; i++) {
    tempLength = 0
    for (let j = i; j < length; j++) {
      if (str[i] === str[j]) {
        tempLength++
      }

      // 不相等 || 已经循环到最后一个
      if (str[i] !== str[j] || j === length - 1) {
        // 与返回值做对比
        if (tempLength > res.length) {
          res.length = tempLength
          res.char = str[i]
        }

        // 跳步
        if (j < length - 1) {
          i = j - 1
        }

        break
      }
    }
  }
  return res
}

/**
 * 找出字符串中连续最多的字符,以及次数 - 双指针
 * @param str
 * @returns
 */
export function findContinuousChar2(str: string): IRes {
  const res: IRes = {
    char: '',
    length: 0
  }

  const length = str.length
  if (length === 0) return res

  // 临时记录连续字符长度
  let tempLength = 0

  let i = 0
  let j = 0

  // O(n)
  for (; i < length; i++) {
    if (str[i] === str[j]) {
      tempLength++
    }

    // 不相等 || 已经循环到最后一个
    if (str[i] !== str[j] || i === length - 1) {
      // 与返回值做对比
      if (tempLength > res.length) {
        res.char = str[j]
        res.length = tempLength
      }

      // 重置临时记录
      tempLength = 0

      if (i < length - 1) {
        j = i // 让“j”追上“i”
        i--
      }
    }
  }

  return res
}
// 功能测试
// const str1 = 'abbcccddeeee1234'
// const res1 = findContinuousChar1(str1)
// console.log(res1)

// const str2 = 'abbcccddeeee1234'
// const res2 = findContinuousChar2(str2)
// console.log(res2)

// 性能测试
let str = ''
for (let i = 0; i < 100 * 10000; i++) {
  str += i.toString()
}
console.time('findContinuousChar1')
findContinuousChar1(str)
console.timeEnd('findContinuousChar1') // 127.184814453125 ms

console.time('findContinuousChar2')
findContinuousChar2(str)
console.timeEnd('findContinuousChar2') // 129.971923828125 ms

单元测试

/**
 * @description 找出字符串中连续最多的字符,以及次数 test
 * @author lsr
 */
import {
  findContinuousChar1,
  findContinuousChar2
} from '@/01-algorithm/continuous-char'

describe('找出字符串中连续最多的字符,以及次数', () => {
  it('最多连续字符在中间', () => {
    const str = 'abbcccddeeee1234'
    const res = findContinuousChar2(str)
    expect(res).toEqual({
      char: 'e',
      length: 4
    })
  })

  it('最多连续字符在开头', () => {
    const str = 'aaaaabbcccddeee1234'
    const res = findContinuousChar2(str)
    expect(res).toEqual({
      char: 'a',
      length: 5
    })
  })

  it('最多连续字符在结尾', () => {
    const str = 'aaaaabbcccddeee123444444'
    const res = findContinuousChar2(str)
    expect(res).toEqual({
      char: '4',
      length: 6
    })
  })

  it('空字符串', () => {
    const str = ''
    const res = findContinuousChar2(str)
    expect(res).toEqual({
      char: '',
      length: 0
    })
  })

  it('无连续字符', () => {
    const str = 'abcdefg'
    const res = findContinuousChar2(str)
    expect(res).toEqual({
      char: 'a',
      length: 1
    })
  })

  it('全都是连续字符', () => {
    const str = 'aaaaa'
    const res = findContinuousChar2(str)
    expect(res).toEqual({
      char: 'a',
      length: 5
    })
  })
})

划重点

  • 要注意实际复杂度,不要被代码表面迷惑
  • 双指针常用于解决嵌套循环
  • 算法题慎用正则表达式(实际工作可用)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值