剑指Offer35-38题解

/**
 * https://leetcode-cn.com/problems/fu-za-lian-biao-de-fu-zhi-lcof/
 *
 * @author Qitong!!
 * @Date 2020/7/5
 */
public class 剑指Offer_35_复杂链表的复制 {
    //利用 HashMap 时间 O(N) 空间 O(N)
    public Node copyRandomList(Node head) {
        if (head == null) return null;

        Map<Node, Node> hashMap = new HashMap<>();
        Node cur = head;
        while (cur != null) {
            hashMap.put(cur, new Node(cur.val));
            cur = cur.next;
        }
        cur = head;
        while (cur != null) {
            hashMap.get(cur).next = hashMap.get(cur.next);
            hashMap.get(cur).random = hashMap.get(cur.random);
            cur = cur.next;
        }
        return hashMap.get(head);
    }

    //进阶解法
    public Node copyRandomList2(Node head) {
        if (head == null) return null;

        //复制链表结点
        Node cur = head;
        while (cur != null) {
            Node copyNode = new Node(cur.val);
            copyNode.next = cur.next;
            cur.next = copyNode;
            cur = copyNode.next;
        }

        //建立 Random 链接
        cur = head;
        while (cur != null) {
            Node copy = cur.next;
            if (cur.random != null) {
                copy.random = cur.random.next;
            }
            cur = copy.next;
        }

        //拆分!!
        cur = head;
        Node newHead = cur.next;
        while (cur.next != null) {
            Node nextNode = cur.next;
            cur.next = nextNode.next;
            cur = nextNode;
        }
        return newHead;
    }
}

/**
 * https://leetcode-cn.com/problems/er-cha-sou-suo-shu-yu-shuang-xiang-lian-biao-lcof/
 *
 * @author Qitong!!
 * @Date 2020/7/5
 */
public class 剑指Offer_36_二叉搜索树与双向链表 {
    TreeNode pre, head;

    public TreeNode treeToDoublyList(TreeNode root) {
        if (root == null) return null;
        inOrder(root);
        //因为是双向链表!!最后将头尾相连,产生关系即可
        pre.right = head;
        head.left = pre;
        return head;
    }

    private void inOrder(TreeNode cur) {
        if (cur == null) return;

        inOrder(cur.left);
        //处理逻辑
        //如果 pre 为空则表示到达中序遍历的第一个结点,即为head
        //不空则 pre的 右指向 现在的结点
        if (pre != null) pre.right = cur;
        else {
            head = cur;
        }
        cur.left = pre;
        pre = cur;

        inOrder(cur.right);
    }
}

/**
 * @author Qitong!!
 * @Date 2020/7/5
 */
public class 剑指Offer_37_序列化二叉树 {

    // Encodes a tree to a single string.
    public String serialize(TreeNode root) {
        //后序序列化!
        if (root == null) return "#!";

        StringBuilder sb = new StringBuilder();
        postSerialize(root, sb);
        return sb.toString();
    }

    private void postSerialize(TreeNode root, StringBuilder sb) {
        if (root.left == null) {
            sb.append("#!");
        } else {
            postSerialize(root.left, sb);
        }
        if (root.right == null) {
            sb.append("#!");
        } else {
            postSerialize(root.right, sb);
        }
        sb.append(root.val).append("!");
    }

    // Decodes your encoded data to tree.
    public TreeNode deserialize(String data) {
        String[] strings = data.split("!");
        Deque<String> deque = new LinkedList<>();

        for (String string : strings) {
            deque.addFirst(string);
        }
        return postDeserialize(deque);
    }

    private TreeNode postDeserialize(Deque<String> deque) {
        String poll = deque.poll();
        if (poll.equals("#")) return null;

        TreeNode head = new TreeNode(Integer.valueOf(poll));
        head.right = postDeserialize(deque);
        head.left = postDeserialize(deque);

        return head;
    }

    public static void main(String[] args) {
        String s = "#";
        System.out.println(s == "#");
    }
}

/**
 * https://leetcode-cn.com/problems/zi-fu-chuan-de-pai-lie-lcof/
 *
 * @author Qitong!!
 * @Date 2020/7/5
 */
public class 剑指Offer_38_字符串的排列 {
    public String[] permutation(String s) {
        char[] chars = s.toCharArray();
        if (chars == null) return null;
        List<String> list = new ArrayList<>();
        if (chars.length == 0) return new String[0];
        dfs(0, chars, list);
        String[] result = new String[list.size()];
        for (int i = 0; i < list.size(); i++) {
            result[i] = list.get(i);
        }
        return result;
    }

    private void dfs(int index, char[] chars, List<String> list) {
        //到最后一层
        if (index == chars.length) {

            list.add(String.valueOf(chars));
            return;
        }

        //枚举这一层可以做的选择
        for (int i = index; i < chars.length; i++) {
            //保证每一个位置只出现一次
            if (isRepeat(chars, index, i)) continue;
            swap(chars, index, i);
            dfs(index + 1, chars, list);
            swap(chars, index, i);
        }
    }

    private boolean isRepeat(char[] chars, int index, int i) {
        for (int j = index; j < i; j++) {
            if (chars[j] == chars[i]) return true;
        }
        return false;
    }

    private void swap(char[] chars, int index, int i) {
        char temp = chars[index];
        chars[index] = chars[i];
        chars[i] = temp;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值