日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

刷题之旅2020.12.05

發布時間:2025/4/16 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 刷题之旅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; }

顏色標記法模板

其核心思想如下:

  • 使用顏色標記節點的狀態,新節點為白色,已訪問的節點為灰色。
  • 如果遇到的節點為白色,則將其標記為灰色,然后將其右子節點、自身、左子節點依次入棧。
  • 如果遇到的節點為灰色,則將節點的值輸出
class Solution {class ColorNode {TreeNode node;String color;public ColorNode(TreeNode node,String color){this.node = node;this.color = color;}}public List<Integer> inorderTraversal(TreeNode root) {if(root == null) return new ArrayList<Integer>();List<Integer> list = new ArrayList<>();Stack<ColorNode> stack = new Stack<>();stack.push(new ColorNode(root,"white"));while(!stack.empty()){ColorNode cn = stack.pop();if(cn.color.equals("white")){// 入棧順序 對應于訪問結果順序(這里為中序,對應 右 根 左)if(cn.node.right != null) stack.push(new ColorNode(cn.node.right,"white")); stack.push(new ColorNode(cn.node,"gray"));if(cn.node.left != null)stack.push(new ColorNode(cn.node.left,"white"));}else{list.add(cn.node.val);}}return list;} } 另一種奇技淫巧,直接判斷棧元素是否為TreeNode public List<Integer> inorderTraversal(TreeNode root) {Stack<Object> stack = new Stack<>();List<Integer> list = new ArrayList<>();if (root == null)return list;stack.push(root);while (!stack.isEmpty()) {Object pop = stack.pop();if (pop instanceof TreeNode) {// 入棧順序 對應于訪問結果順序(這里為中序,對應 右 根 左)TreeNode treeNode = (TreeNode) pop;if (treeNode.right != null) {stack.push(treeNode.right);}stack.push(new Integer(treeNode.val));if (treeNode.left != null) {stack.push(treeNode.left);}} else {list.add((Integer)pop);}}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的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。