11. 盛最多水的容器

给定 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

说明:你不能倾斜容器,且 n 的值至少为 2。

upload successful

解: 1.如果可以使用暴力,很多事情就变得简单了。

  • code
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    func maxArea(height []int) int {
    s:=0
    for i:=0 ;i<len(height)-1;i++{
    for j:=i+1;j<len(height);j++{
    a:=height[j]*(j-i)
    if height[j]> height[i]{
    a = height[i]*(j-i)
    }
    if a > s{
    s = a
    }
    }
    }
    return s
    }

2.双指针法

  • code

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    func maxArea(height []int) int {
    l := len(height)
    s := 0
    i,j := 0,l-1
    for i<j {
    var s1 int
    if height[i]<height[j]{
    s1 = height[i]*(j-i)
    i++
    }else{
    s1 = height[j]*(j-i)
    j--
    }
    if s1 > s{
    s = s1
    }
    }
    return s
    }

12. 整数转罗马数字

罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。

字符 数值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。

通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:

I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。
给定一个整数,将其转为罗马数字。输入确保在 1 到 3999 的范围内。

  • code

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    func intToRoman(num int) string {
    var base = []int{1000,900, 500,400, 100,90, 50,40, 10,9,5,4,1}
    var strs = []string{"M","CM", "D","CD","C","XC","L","XL","X", "IX","V","IV","I"}
    ret := ""
    for i,b:=range base{
    x := num/b
    num = num%b
    if x!=0{
    for j:=0;j<x;j++{
    ret +=strs[i]
    }
    }
    }
    return ret
    }

13. 罗马数字转整数

罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。

字符 数值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。

通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:

I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。
给定一个罗马数字,将其转换成整数。输入确保在 1 到 3999 的范围内。

  • code

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    func romanToInt(s string) int {
    var base = []int{1000,900, 500,400, 100,90, 50,40, 10,9,5,4,1}
    var strs = []string{"M","CM", "D","CD","C","XC","L","XL","X", "IX","V","IV","I"}

    ret:=0
    for i:=0;i< len(strs);{
    if strings.HasPrefix(s,strs[i]){
    ret+=base[i]
    s = s[len(strs[i]):]
    }else{
    i++
    }
    }
    return ret
    }

14. 最长公共前缀

编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 “”。

  • code

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    func longestCommonPrefix(strs []string) string {
    if len(strs)==0{ // 如果空,返回“”
    return ""
    }
    base:=strs[0] // 选取第一个字符串作为对比基串
    for i:=0;i<len(base);i++{
    b:=base[i]
    for j:=1;j<len(strs);j++{ // 按索引对比
    if i>=len(strs[j]) || strs[j][i]!=b{
    return base[:i] // 不想等就返回
    }
    }
    }
    return base
    }

15. 三数之和

给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]

解: 1.分层循环

  • code

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    func threeSum(nums []int) [][]int {
    sort.Ints(nums)
    ret := [][]int{}
    l:=len(nums)
    for i:=0;i< l-2; i++{
    if nums[i] > 0 {
    break
    }
    if i>0 && nums[i] == nums[i-1]{
    continue
    }
    ts := twoSum(nums[i+1:], -nums[i])
    for _,s:=range ts{
    ret = append(ret, []int{nums[i], s[0], s[1]})
    }
    }
    return ret
    }

    func twoSum(nums []int, n int)[][]int{
    ret := [][]int{}
    for i:=0; i<len(nums)-1;i++{
    if nums[i]>n/2{
    break
    }
    if i>0 && nums[i] == nums[i-1]{
    continue
    }
    o,has := one(nums[i+1:], n-nums[i])
    if has{
    ret = append(ret, []int{nums[i], o})
    }
    }
    return ret
    }


    func one(nums []int,n int) (int,bool) {
    end:=len(nums)-1
    start:=0
    if nums[start] == n{
    return nums[start],true
    }
    if nums[end] == n{
    return nums[end],true
    }
    for start<end {
    mid := (start+end)/2
    if mid > start{
    if nums[mid] == n{
    return nums[mid],true
    }
    if nums[mid]>n {
    end = mid
    }else{
    start = mid
    }
    }else{
    break
    }
    }

    return 0,false
    }

2.三指针法

  • code

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    func threeSum(nums []int) [][]int {
    ret := [][]int{}
    sort.Ints(nums)

    for i:=0; i<len(nums)-2; i++{
    if nums[i] > 0{
    break
    }
    if i > 0 && nums[i] == nums[i-1]{
    continue
    }

    j, k := i+1, len(nums)-1
    for j<k {
    if j > i+1 && nums[j] == nums[j-1]{
    j++
    continue
    }
    if nums[i] + nums[j] + nums[k] == 0{
    ret = append(ret, []int{nums[i], nums[j], nums[k]})
    j++
    k--
    }else if nums[i] + nums[j] + nums[k] > 0{
    k--
    }else{
    j++
    }
    }
    }
    return ret
    }

16. 最接近的三数之和

给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在唯一答案。
例如,给定数组 nums = [-1,2,1,-4], 和 target = 1.
与 target 最接近的三个数的和为 2. (-1 + 2 + 1 = 2).

解: 三指针

  • code
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    func threeSumClosest(nums []int, target int) int {
    sort.Ints(nums)
    det:=0

    for i:=0; i<len(nums)-2; i++{
    if i == 0{
    det = nums[0] + nums[1] + nums[len(nums)-1] - target
    }else if nums[i] == nums[i-1]{
    continue
    }

    j, k := i+1, len(nums)-1
    for j<k {
    if j > i+1 && nums[j] == nums[j-1]{
    j++
    continue
    }
    temp := nums[i] + nums[j] + nums[k] - target
    if temp == 0{
    return target
    }else {
    if abs(temp)< abs(det) {
    det = temp
    }
    if temp < 0{
    j++
    }else{
    k--
    }
    }
    }
    }
    return det + target
    }

    func abs(n int)int{
    if n < 0{
    return -n
    }
    return n
    }

17. 电话号码的字母组合

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

upload successful

  • code

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    // 当然可以做复用
    func letterCombinations(digits string) []string {
    numMap := map[byte][]string{
    '2': []string{"a", "b", "c"},
    '3': []string{"d", "e", "f"},
    '4': []string{"g", "h", "i"},
    '5': []string{"j", "k", "l"},
    '6': []string{"m", "n", "o"},
    '7': []string{"p", "q", "r", "s"},
    '8': []string{"t", "u", "v"},
    '9': []string{"w", "x", "y", "z"},
    }
    if len(digits) == 0{
    return nil
    }

    fm := numMap[digits[0]]
    if len(digits) == 1{
    return fm
    }
    em := letterCombinations(digits[1:])
    ret := []string{}
    for _,f := range fm{
    for _,e:=range em{
    ret = append(ret , f+e)
    }
    }
    return ret
    }

18. 四数之和

给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?找出所有满足条件且不重复的四元组。

注意:

答案中不可以包含重复的四元组。

示例:

给定数组 nums = [1, 0, -1, 0, -2, 2],和 target = 0。

满足要求的四元组集合为:
[
[-1, 0, 0, 1],
[-2, -1, 1, 2],
[-2, 0, 0, 2]
]

解:有一句mmp,不知当讲不当讲

  • code

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    func fourSum(nums []int, target int) [][]int {
    sort.Ints(nums)
    return kSum(nums, 4, target)
    }


    // k>=2
    func kSum(nums []int, k, target int)[][]int{
    ret := [][]int{}
    if k == 2{
    i, j := 0, len(nums)-1
    for i < j{
    if nums[i] > target/2{
    break
    }
    if i > 0 && nums[i] == nums[i-1]{
    i++
    continue
    }
    if nums[i] + nums[j] == target{
    ret = append(ret, []int{nums[i], nums[j]})
    i++
    j--
    }else if nums[i] + nums[j] < target{
    i++
    }else{
    j--
    }
    }
    }else{
    for i:=0; i<len(nums) - k + 1; i++{
    if nums[i] > target/k {
    break
    }
    if i > 0 && nums[i] == nums[i-1]{
    continue
    }
    ts := kSum(nums[i+1:], k-1, target-nums[i])
    for j:=range ts{
    r := make([]int, k)
    r[0] = nums[i]
    copy(r[1:], ts[j])
    ret = append(ret,r)
    }
    }
    }
    return ret
    }

19. 删除链表的倒数第N个节点

给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。

解: 从头节点与第n个节点同时移动,后一个节点移动至末尾,头节点将移动至倒数第n个节点

  • code

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    /**
    * Definition for singly-linked list.
    * type ListNode struct {
    * Val int
    * Next *ListNode
    * }
    */

    func removeNthFromEnd(head *ListNode, n int) *ListNode {

    first := head
    for i := 1; i < n; i++ {
    first = first.Next
    }

    var npNode *ListNode
    second := head
    for first.Next != nil {
    first = first.Next
    npNode = second
    second = second.Next
    }
    if npNode == nil {
    return second.Next
    }
    npNode.Next = second.Next
    return head
    }

20. 有效的括号

给定一个只包括 ‘(‘,’)’,’{‘,’}’,’[‘,’]’ 的字符串,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。

解: 经典栈

  • code
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    func isValid(s string) bool {
    var match = map[byte]byte{
    ')':'(',
    ']':'[',
    '}':'{',
    }
    stack := []byte{}
    for _,b:= range []byte(s){
    switch b{
    case '(','{','[':
    stack = append(stack, b)
    case ')','}',']':
    if len(stack) == 0 || stack[len(stack)-1] != match[b]{
    return false
    }
    stack = stack[:len(stack)-1]
    }
    }
    return len(stack) == 0
    }