ARTS 打卡第六周

ARTS 打卡week06

在这里插入图片描述

每周完成一个 ARTS:

Algorithm: 每周至少做一个 LeetCode 的算法题

Review: 阅读并点评至少一篇英文技术文章

Tips: 学习至少一个技术技巧

Share: 分享一篇有观点和思考的技术文章

Algorithm

15. 三数之和
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,
使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。

注意:答案中不可以包含重复的三元组。
示例
给定数组 nums = [-1, 0, 1, 2, -1, -4],

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

0015_three_sum.go

// ans_1: Exhaustive method (encounter timeout)
func ThreeSum01(nums []int) [][]int {
	flagI, res := false, [][]int{}
	sort.Ints(nums)
	for i, _ := range nums {
        // repeat element ignore
		if flagI == true && nums[i] == nums[i-1] {
			continue
		}
		if !flagI {
			flagI = true
		}
        // flagJ should be initialized after a loop
		flagJ := false
		for j, _ := range nums {
            // repeat element ignore
			if j <= i || (flagJ == true && nums[j] == nums[j-1]){
				continue
			}
			if !flagJ {
				flagJ = true
			}
			flagK := false
			for k, _ := range nums {
				if k <= j || (flagK == true && nums[k] == nums[k-1]){
					continue
				}
				if !flagK {
					flagK = true
				}
				if nums[i] + nums[j] + nums[k] == 0 {
					res = append(res, []int{nums[i], nums[j], nums[k]})
				}
			}
		}
	}
	return res
}

// ans_2: use the property of c = -(a + b)
// create a map and store sorted nums elements
// enumerate a, b value, if -(a+b) exists in map, store elements into res
// caution: remove repeate result
func ThreeSum02(nums []int) [][]int {
	sort.Ints(nums)
	res := [][]int{}
	set := make(map[int]int, len(nums))
	for index, value := range nums {
		set[value] = index
	}

	for i, valueI := range nums {
        // remove repeat result
		if i > 0 && nums[i] == nums[i-1] {
			continue
		}
		for j, valueJ := range nums {
            // remove repeat result
			if j <= i || (j > i + 1 && nums[j] == nums[j-1]) {
				continue
			}
			// remove repeat result
			if value, ok := set[-(valueI+valueJ)]; ok && value > j {
				res = append(res, []int{valueI, valueJ, -(valueI+valueJ)})
			}
		}
	}

	return res
}

// ans_3: use left index and right index
func ThreeSum03(nums []int) [][]int {
	sort.Ints(nums)
	res := [][]int{}
	set := make(map[int]int, len(nums))
	for index, value := range nums {
		set[value] = index
	}

	for i, value := range nums {
		if i > 0 && nums[i] == nums[i-1] {
			continue
		}

		for j, k := i+1, len(nums)-1; j < k; {
			switch {
			case value+nums[j]+nums[k] > 0:
				k--
			case value+nums[j]+nums[k] < 0:
				j++
			default:
				res = append(res, []int{nums[i], nums[j], nums[k]})
			I:
				for j < k {
					switch {
					case nums[j] == nums[j+1]:
						j++
					case nums[k] == nums[k-1]:
						k--
					default:
						j++
						k--
						break I
					}
				}
			}
		}
	}

	return res
}

0015_three_sum.go

package leetCode

import (
	"fmt"
	"github.com/stretchr/testify/assert"
	"testing"
)

type question0015 struct {
	para0015
	ans0015
}

// para0015 是参数
// one 代表第一个参数
type para0015 struct {
	one []int
}

// ans0015 是答案
// one 代表第一个答案
type ans0015 struct {
	one [][]int
}

func Test_Problem0015(t *testing.T) {
	ast := assert.New(t)
	qs := []question0015{
		question0015{
			para0015{[]int{-1,0,1,2,-1,-4}},
			ans0015{[][]int{
				[]int{-1, 0, 1},
				[]int{-1, -1, 2},
			}},
		},
		// 如需多个测试,可以复制上方元素。
	}

	for _, q := range qs {
		a, p := q.ans0015, q.para0015

		ast.Equal(a.one, ThreeSum03(p.one), "输入:%v", p)
		fmt.Println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
	}
}

Review

Tips

  • for range 结构是Go语言特有的一种的迭代结构,在许多情况下都非常有用,for range 可以遍历数组、切片、字符串、map 及通道(channel),for range 语法上类似于其它语言中的 foreach 语句,一般形式为:

    for key, val := range coll {
        ...
    }
    
  • 通过 for range 遍历的返回值有一定的规律:

    /*
    - 数组、切片、字符串返回索引和值。
    - map 返回键和值。
    - 通道(channel)只返回通道内的值。
    */
    for key, value := range []int{1, 2, 3, 4} {
        fmt.Printf("key:%d  value:%d\n", key, value)
    }
    
    var str = "hello 你好"
    for key, value := range str {
        fmt.Printf("key:%d value:0x%x\n", key, value)
    }
    
    m := map[string]int{
        "hello": 100,
        "world": 200,
    }
    for key, value := range m {
        fmt.Println(key, value)
    }
    
    c := make(chan int)
    go func() {
        c <- 1
        c <- 2
        c <- 3
        close(c)
    }()
    for v := range c {
        fmt.Println(v)
    }
    

    注:

    这里的 value 映射的值使用的是同一个地址,而不是直接返回每个元素的应用,如果使用该变量的地址作为指向的每个元素的指针,会出错。

    for range 元素的顺序为 index, value (fuck, 经常忘记顺序)

  • map 遍历时顺序不固定

    func main() {
        m := map[string]string{
            "1": "1",
            "2": "2",
            "3": "3",
        }
    
        for k, v := range m {
            println(k, v)
        }
    }
    

Share

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值