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