Golang每日一练(leetDay0056) 单个编辑距离、寻找峰值

简介: Golang每日一练(leetDay0056) 单个编辑距离、寻找峰值

161. 单个编辑距离 One Edit Distance


给定两个字符串 s 和 t,判断他们的编辑距离是否为 1。


注意:


满足编辑距离等于 1 有三种可能的情形:


往 s 中插入一个字符得到 t

从 s 中删除一个字符得到 t

在 s 中替换一个字符得到 t


示例 1:

输入: s = "ab", t = "acb"

输出: true

解释: 可以将 'c' 插入字符串 s 来得到 t。


示例 2:

输入: s = "cab", t = "ad"

输出: false

解释: 无法通过 1 步操作使 s 变为 t。


示例 3:

输入: s = "1203", t = "1213"

输出: true

解释: 可以将字符串 s 中的 '0' 替换为 '1' 来得到 t。


代码1: 暴力枚举

package main
import "fmt"
func isOneEditDistance(s string, t string) bool {
  m, n := len(s), len(t)
  if m > n {
    return isOneEditDistance(t, s)
  }
  if n-m > 1 {
    return false
  }
  for i := 0; i < m; i++ {
    if s[i] != t[i] {
      if m == n {
        return s[i+1:] == t[i+1:]
      } else {
        return s[i:] == t[i+1:]
      }
    }
  }
  return m+1 == n
}
func main() {
  s := "ab"
  t := "acb"
  fmt.Println(isOneEditDistance(s, t))
  s = "cab"
  t = "ad"
  fmt.Println(isOneEditDistance(s, t))
  s = "1203"
  t = "1213"
  fmt.Println(isOneEditDistance(s, t))
}

暴力枚举2:

```go
func findPeakElement(nums []int) int {
    n := len(nums)
    for i := 0; i < n; i++ {
        if (i == 0 || nums[i] > nums[i-1]) && (i == n-1 || nums[i] > nums[i+1]) {
            return i
        }
    }
    return -1
}
``` 


代码2: 递归

package main
import "fmt"
func isOneEditDistance(s string, t string) bool {
  if len(s) > len(t) {
    return isOneEditDistance(t, s)
  }
  if len(t)-len(s) > 1 {
    return false
  }
  if len(s) == 0 && len(t) == 0 {
    return false
  } else if len(s) == 0 || len(t) == 0 {
    return true
  } else if s[0] == t[0] {
    return isOneEditDistance(s[1:], t[1:])
  } else if len(s) == len(t) {
    return s[1:] == t[1:] || s[1:] == t[:] || s[:] == t[1:]
  } else {
    return s[:] == t[1:]
  }
}
func main() {
  s := "ab"
  t := "acb"
  fmt.Println(isOneEditDistance(s, t))
  s = "cab"
  t = "ad"
  fmt.Println(isOneEditDistance(s, t))
  s = "1203"
  t = "1213"
  fmt.Println(isOneEditDistance(s, t))
}



代码3: 迭代

package main
import "fmt"
func isOneEditDistance(s string, t string) bool {
  m, n := len(s), len(t)
  if m > n {
    return isOneEditDistance(t, s)
  }
  if n-m > 1 {
    return false
  }
  i, j := 0, 0
  edited := false
  for i < m && j < n {
    if s[i] == t[j] {
      i++
      j++
    } else {
      if edited {
        return false
      }
      edited = true
      if m == n {
        i++
        j++
      } else {
        j++
      }
    }
  }
  return edited || i < m
}
func main() {
  s := "ab"
  t := "acb"
  fmt.Println(isOneEditDistance(s, t))
  s = "cab"
  t = "ad"
  fmt.Println(isOneEditDistance(s, t))
  s = "1203"
  t = "1213"
  fmt.Println(isOneEditDistance(s, t))
}

输出:

true

false

true


162. 寻找峰值 Find Peak Element


峰值元素是指其值严格大于左右相邻值的元素。


给你一个整数数组 nums,找到峰值元素并返回其索引。数组可能包含多个峰值,在这种情况下,返回 任何一个峰值 所在位置即可。


你可以假设 nums[-1] = nums[n] = -∞ 。

你必须实现时间复杂度为 O(log n) 的算法来解决此问题。


示例 1:

输入:nums = [1,2,3,1]

输出:2

解释:3 是峰值元素,你的函数应该返回其索引 2。


示例 2:

输入:nums = [1,2,1,3,5,6,4]

输出:1 或 5  

解释:你的函数可以返回索引 1,其峰值元素为 2;

    或者返回索引 5, 其峰值元素为 6。


提示:

   1 <= nums.length <= 1000

   -2^31 <= nums[i] <= 2^31 - 1

   对于所有有效的 i 都有 nums[i] != nums[i + 1]


代码1: 暴力枚举

package main
import "fmt"
func findPeakElement(nums []int) int {
  n := len(nums)
  if n == 1 {
    return 0
  }
  for i := 0; i < n; i++ {
    if i == 0 {
      if nums[i] > nums[i+1] {
        return i
      }
    } else if i == n-1 {
      if nums[i] > nums[i-1] {
        return i
      }
    } else {
      if nums[i] > nums[i-1] && nums[i] > nums[i+1] {
        return i
      }
    }
  }
  return -1
}
func main() {
  nums := []int{1, 2, 3, 1}
  fmt.Println(findPeakElement(nums))
  nums = []int{1, 2, 1, 3, 5, 6, 4}
  fmt.Println(findPeakElement(nums))
}


输出:

2

1

代码2: 二分查找

package main
import "fmt"
func findPeakElement(nums []int) int {
  n := len(nums)
  if n == 1 {
    return 0
  }
  left, right := 0, n-1
  for left < right {
    mid := left + (right-left)/2
    if nums[mid] < nums[mid+1] {
      left = mid + 1
    } else {
      right = mid
    }
  }
  return left
}
func main() {
  nums := []int{1, 2, 3, 1}
  fmt.Println(findPeakElement(nums))
  nums = []int{1, 2, 1, 3, 5, 6, 4}
  fmt.Println(findPeakElement(nums))
}

递归形式:

```go
func findPeakElement(nums []int) int {
    return search(nums, 0, len(nums)-1)
}
func search(nums []int, left, right int) int {
    if left == right {
        return left
    }
    mid := left + (right-left)/2
    if nums[mid] > nums[mid+1] {
        return search(nums, left, mid)
    }
    return search(nums, mid+1, right)
}
``


输出:

2

5

目录
打赏
0
0
0
0
74
分享
相关文章
|
10月前
|
Shell编程——弱数据类型的脚本语言快速入门指南
Shell编程——弱数据类型的脚本语言快速入门指南
121 0
Shell编程——弱数据类型的脚本语言快速入门指南
|
10月前
|
Linux 终端命令之文件浏览(2) more
Linux 终端命令之文件浏览(2) more
83 0
Linux 终端命令之文件浏览(2) more
Linux 终端操作命令(2)内部命令
Linux 终端操作命令(2)内部命令
127 0
Linux 终端操作命令(2)内部命令
|
10月前
|
力扣 C++|一题多解之动态规划专题(2)
力扣 C++|一题多解之动态规划专题(2)
111 0
力扣 C++|一题多解之动态规划专题(2)
|
10月前
|
Python Numpy入门基础(一)创建数组
Python Numpy入门基础(一)创建数组
124 0
Python Numpy入门基础(一)创建数组
|
10月前
|
Java语言程序设计试卷6套
Java语言程序设计试卷6套
986 0
Java语言程序设计试卷6套
|
10月前
|
Golang每日一练(leetDay0120) 反转字符串中的元音字母、前K个高频元素
Golang每日一练(leetDay0120) 反转字符串中的元音字母、前K个高频元素
107 0
Golang每日一练(leetDay0120) 反转字符串中的元音字母、前K个高频元素
|
6月前
|
Go
Golang语言之管道channel快速入门篇
这篇文章是关于Go语言中管道(channel)的快速入门教程,涵盖了管道的基本使用、有缓冲和无缓冲管道的区别、管道的关闭、遍历、协程和管道的协同工作、单向通道的使用以及select多路复用的详细案例和解释。
203 4
Golang语言之管道channel快速入门篇
|
6月前
|
Go
Golang语言文件操作快速入门篇
这篇文章是关于Go语言文件操作快速入门的教程,涵盖了文件的读取、写入、复制操作以及使用标准库中的ioutil、bufio、os等包进行文件操作的详细案例。
100 4
Golang语言文件操作快速入门篇
|
6月前
|
Go
Golang语言之gRPC程序设计示例
这篇文章是关于Golang语言使用gRPC进行程序设计的详细教程,涵盖了RPC协议的介绍、gRPC环境的搭建、Protocol Buffers的使用、gRPC服务的编写和通信示例。
172 3
Golang语言之gRPC程序设计示例