内容简介:leetcode题目输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)输出:7 -> 0 -> 8
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)
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 理解原型其实是理解原型链
- 要理解深度学习,必须突破常规视角去理解优化
- 深入理解java虚拟机(1) -- 理解HotSpot内存区域
- 荐 【C++100问】深入理解理解顶层const和底层const
- 深入理解 HTTPS
- 深入理解 HTTPS
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。