刷题之旅2020.12.05
2020.12.05
1.前中后序 遞歸/非遞歸 實現(xiàn)
一、使用棧模擬遞歸實現(xiàn)過程
先序/中序
public List preinOrder2(TreeNode root){if(root==null)return;Stack<TreeNode> s=new Stack<>();List list = new LinkedList();while(root!=null || !s.isEmpty()){//不斷往左子樹方向走,每走一次就將當(dāng)前節(jié)點保存到棧中//這是模擬遞歸的調(diào)用if(root != null){list.add(root.val); //這里訪問順序是先序s.push(root);root = root.left;//當(dāng)前節(jié)點為空,說明左邊走到頭了,從棧中彈出節(jié)點并保存//然后轉(zhuǎn)向右邊節(jié)點,繼續(xù)上面整個過程}else{root = s.pop();list.add(root.val); //這里訪問順序是中序root = root.right;}} }后序(模擬遞歸實現(xiàn))
class Solution {public List<Integer> postorderTraversal(TreeNode root) {List<Integer> res = new ArrayList<Integer>();if (root == null) {return res;}Deque<TreeNode> stack = new LinkedList<TreeNode>();TreeNode prev = null;while (root != null || !stack.isEmpty()) {while (root != null) {stack.push(root);root = root.left;}root = stack.pop();if (root.right == null || root.right == prev) {res.add(root.val);prev = root;root = null;} else {stack.push(root);root = root.right;}}return res;} }后序(利用前序?qū)崿F(xiàn)「根-左-右」—> 「右-左-根」—> 「左-右-根」)
public List postorder(TreeNode root){TreeNode node = new TreeNode();Stack stack = new Stack();List list = new LinkedList();while(!stack.isEmpty() || root!=null){if(root != null){//頭插法List.addFirst(root.val);stack.push(root);//優(yōu)先訪問右子樹root = root.right;}else {root = stack.pop();root = root.left;}}return list; }顏色標(biāo)記法模板
其核心思想如下:
- 使用顏色標(biāo)記節(jié)點的狀態(tài),新節(jié)點為白色,已訪問的節(jié)點為灰色。
- 如果遇到的節(jié)點為白色,則將其標(biāo)記為灰色,然后將其右子節(jié)點、自身、左子節(jié)點依次入棧。
- 如果遇到的節(jié)點為灰色,則將節(jié)點的值輸出
鏈表
1.兩兩交換鏈表中節(jié)點 (leetcode24)
思路:可以使用迭代或者遞歸實現(xiàn)
迭代實現(xiàn):
新建啞結(jié)點nHead,令nHead.next = head,令 temp 表示當(dāng)前到達(dá)的節(jié)點,初始時 temp = nHead。每次需要交換 temp 后面的兩個節(jié)點即可,如果 temp 的后面沒有節(jié)點或者只有一個節(jié)點,則沒有更多的節(jié)點需要交換,因此結(jié)束交換。否則,獲得 temp 后面的兩個節(jié)點 node1 和 node2,通過更新節(jié)點的指針關(guān)系實現(xiàn)兩兩交換節(jié)點。
public ListNode swapPairs(ListNode head) {if (head == null || head.next == null)return head;ListNode nHead = new ListNode(-1);nHead.next = head;ListNode temp = nHead;while (temp.next != null && temp.next.next != null) {ListNode nNext = temp.next.next;temp.next.next = nNext.next;nNext.next = temp.next;temp.next = nNext;temp = nNext.next;}return nHead.next; }遞歸實現(xiàn):
終止條件為head == null || head.next == null;
遞歸思路就是假設(shè)head.next.next后面已經(jīng)完成兩兩交換,并返回,即temp = swapPairs(head.next.next);
則單次遞歸執(zhí)行邏輯為:ListNode newHead = head.next; head.next = temp;newHead.next = head;
class Solution {public ListNode swapPairs(ListNode head) {if (head == null || head.next == null) {return head;}ListNode newHead = head.next;head.next = swapPairs(newHead.next);newHead.next = head;return newHead;} }2.反轉(zhuǎn)鏈表||(leetcode92)
輸入: 1->2->3->4->5->NULL, m = 2, n = 4 輸出: 1->4->3->2->5->NULL反轉(zhuǎn)從位置m到n的鏈表。思想:在第m節(jié)點的前一個位置(這里指向1)設(shè)為pre節(jié)點,利用cur指針(這里指向2)依次將cur節(jié)點的后置節(jié)點插入到pre后面,執(zhí)行邏輯為:ListNode nxt = cur.next;cur.next = nxt.next;nxt.next = pre.next;pre.next = nxt;
public ListNode reverseBetween(ListNode head, int m, int n) {if (head == null) return null;ListNode pre = new ListNode(-1);ListNode nHead = pre;pre.next = head;for (int i=1; i<m; i++) {pre = pre.next;}ListNode cur = pre.next;for (int i=m; i<n; i++) {ListNode nxt = cur.next;cur.next = nxt.next;nxt.next = pre.next;pre.next = nxt;}return nHead.next;}總結(jié)
以上是生活随笔為你收集整理的刷题之旅2020.12.05的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 理解进程创建、可执行文件的加载和进程执行
- 下一篇: 2020.12.15