1、不使用递归
a. 链表间运算(逐位相加)
leetcode题目 示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
//副本
node1 := l1
node2 := l2
//初始链表节点,指针才能与nil相比较
headNode := &ListNode{
Val: 0,
Next: nil,
}
nowNode := headNode
//溢出位
flag := 0
for (node1 != nil) || (node2 != nil) {
v1 := 0
if node1 != nil {
v1 = node1.Val
node1 = node1.Next
}
v2 := 0
if node2 != nil {
v2 = node2.Val
node2 = node2.Next
}
sv := v1 + v2 + flag
if sv < 10 {
flag = 0
}else{
sv = sv - 10
flag = 1
}
//1. 副本找到最新节点 的指针,逐个连接
if nowNode.Next != nil {
nowNode = nowNode.Next
}
//2. 新建插入节点 的指针
join := &ListNode{ Val: sv, Next: nil, }
//3. 替换空指针
nowNode.Next = join
}
//数据有溢出位
if flag == 1 {
join := &ListNode{ Val: 1, Next: nil, }
nowNode = nowNode.Next
nowNode.Next = join
}
return headNode.Next
}
小结&注意:
- 副本的拷贝:指针传递,避免遍历迭代时污染源数据;
- 锚点:核心,新节点添加到当前的next,如果next有了、下个next;
nowNode := headNode
|| if nowNode.Next != nil { nowNode = nowNode.Next }
b. 链表合并、排序
示例:
输入:
[
1->4->5,
1->3->4,
2->6
]
输出: 1->1->2->3->4->4->5->6
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func mergeKLists(lists []*ListNode) *ListNode {
headNode := &ListNode{
Val: 0,
Next: nil,
}
nowNode := headNode
//合并,搜集排序值到slice
var s []int
for _,nodes := range(lists) {
for nodes != nil {
if nowNode.Next!=nil {
nowNode = nowNode.Next
}
nowNode.Next = &ListNode{
Val: nodes.Val,
Next: nil,
}
s = append(s, nodes.Val)
nodes = nodes.Next
}
}
comNode := headNode.Next
//排序
newHeadNode := &ListNode{
Val: 0,
Next: nil,
}
nowNode = newHeadNode
for i:=0; i<len(s)-1; i++ {
for j:=i+1; j<len(s); j++ {
if s[i]>s[j] {
temp := s[i]
s[i] = s[j]
s[j] = temp
}
}
}
//重新组合
for i:=0; i<len(s); i++ {
for {
if comNode.Val == s[i] {
nowNode.Next = &ListNode{
Val: comNode.Val,
Next: nil,
}
nowNode = nowNode.Next
break;
}
//指针回拨
if comNode.Next==nil {
comNode = headNode.Next
}else{
comNode = comNode.Next
}
}
}
return newHeadNode.Next
}
小结:
- 核心:副本和锚点。
2、正向递归、反向递归
a. 斐波那契数列
正向递归:
每项等于前2项之和 公式f[n]=f[n-1]+f[n-2]
func fibonacci(n int) int {
if n=1 {
return 0
} else if n= 2 {
return 1
} else {
return fibonacci(n-2) + fibonacci(n-1)
}
}
fibonacci(10)
b. 猴子吃桃
反向递归 问题:
有一堆桃子,猴子第一天吃了其中的一半,并在多吃了一个。以后猴子每天都吃其中的一半,然后再多吃一个,当到第10天时,发现只有一个桃子了。问题:最初共有多少个桃子?
func has_peach(n int) int {
if n=10 {
return 1
} else {
return (has_peach(n+1)+1) * 2
}
}
has_peach(1)
有疑问加站长微信联系(非本文作者)