每周完成一个 ARTS:
Algorithm: 每周至少做一个 LeetCode 的算法题
Review: 阅读并点评至少一篇英文技术文章
Tips: 学习至少一个技术技巧
Share: 分享一篇有观点和思考的技术文章
Algrithm
2.两数相加
给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
解析
addTwoNums.go
package leetCode
/*
** 解析:
** 创建两个链表分别为 l1, l2
** 1.先确保两个链表长度一样
** 2.对链表的各个节点求和,暂不考虑进位问题
** 3.处理进位问题
** 4.返回链表指针
*/
type ListNode struct {
Val int
Next *ListNode
}
func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
tempL1, tempL2 := l1, l2
tl1, tl2 := l1, l2
// 保证两个链表长度一样
for tempL1 != nil && tempL2 != nil {
if tempL1.Next != nil && tempL2.Next == nil {
tempL2.Next = &ListNode{}
}
if tempL1.Next == nil && tempL2.Next != nil {
tempL1.Next = &ListNode{}
}
tempL1 = tempL1.Next
tempL2 = tempL2.Next
}
// 两个链表各个结点相加,暂不考虑进位
resList := &ListNode{}
temp1 := resList
for {
temp1.Val = tl1.Val + tl2.Val
if tl1, tl2 = tl1.Next, tl2.Next; tl1 == nil && tl2 == nil {
break
}
temp1.Next = &ListNode{}
temp1 = temp1.Next
}
/*定义一个进位变量carry,对每个结点进行除10操作,大于0则赋值给carry,carry参与下一个结点的取值计算*/
temp := resList
tempVal, carry := 0, 0
for {
tempVal = (temp.Val + carry) % 10
carry = (temp.Val + carry) / 10
temp.Val = tempVal
if temp.Next == nil {
if carry > 0 {
temp.Next = &ListNode{}
temp.Next.Val = carry
}
break
} else {
temp = temp.Next
}
}
return resList
}
addTwoNums_test.go(测试demo我直接用github的例子了)
package leetCode
import (
"testing"
"github.com/stretchr/testify/assert"
)
type para struct {
one *ListNode
two *ListNode
}
type ans struct {
one *ListNode
}
type question struct {
p para
a ans
}
func makeListNode(is []int) *ListNode {
if len(is) == 0 {
return nil
}
res := &ListNode{
Val: is[0],
}
temp := res
for i := 1; i < len(is); i++ {
temp.Next = &ListNode{Val: is[i]}
temp = temp.Next
}
return res
}
func Test_OK(t *testing.T) {
ast := assert.New(t)
qs := []question{
question{
p: para{
one: makeListNode([]int{5}),
two: makeListNode([]int{5}),
},
a: ans{
one: makeListNode([]int{0,1}),
},
},
}
for _, q := range qs {
a, p := q.a, q.p
ast.Equal(a.one, addTwoNumbers(p.one, p.two), "输入:%v", p)
}
}
Review
《How to deal with technical debt》
总结如下:
1.针对一个需求,不要只着眼于当下的任务,需要考虑系统整体结构的影响;
2.争取每天都比昨天优秀1%;
3.把责任感融入整个团队,让团队更加优秀。
Tips
mongodb 执行查询语句,检查是否走索引
db.users.find({gender:"M"},{user_name:1,_id:0}).explain()
// output
{
"cursor":"BtreeCursor gender_1_user_name_1",
"isMultiKey":false, // 本次查询是否使用了多键、复合索引
"n":1, // 当前查询返回的文档数量
"nscannedObjects":0, // 数据库按照索引去磁盘上查找实际文档的次数
"nscanned":1, // 表明当前这次查询一共扫描了集合中多少个文档,我们的目的是,让这个数值和返回文档的数量越接近越
"nscannedObjectsAllPlans":0,
"nscannedAllPlans":1,
"scanAndOrder":false, // 是否在内存中对结果进行了排序
"indexOnly":true, // 字段为 true ,表示我们使用了索引
"nYields":0, // 本次查询的暂停次数
"nChunkSkips":0,
"millis":0, // 当前查询所需时间
"indexBounds":{ // 描述索引的使用情况
"gender":[
[
"M",
"M"
]
],
"user_name":[
[
{
"$minElement":1
},
{
"$maxElement":1
}
]
]
}
}
Share
comming soon