《剑指offer》剖析让复杂问题更简朴

1.庞杂链表的复制

输入一个庞杂链表(每一个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特别指针指向恣意一个节点),返回效果为复制后庞杂链表的head。(注重,输出效果中请不要返回参数中的节点援用)

思绪

拆分红三步

1.复制一份链表放在前一个节点背面,即依据原始链表的每一个节点N建立N,把N直接放在N的next位置,让复制后的链表和原始链表构成新的链表。

2.给复制的链表random赋值,即N`.random=N.random.next。

3.拆分链表,将N`和N举行拆分,保证原始链表不受影响。

代码

    function Clone(pHead) {
      if (pHead === null) {
        return null;
      }
      cloneNodes(pHead);
      cloneRandom(pHead);
      return reconnetNodes(pHead);
    }

    function cloneNodes(pHead) {
      var current = pHead;
      while (current) {
        var cloneNode = {
          label: current.label,
          next: current.next
        };
        current.next = cloneNode;
        current = cloneNode.next;
      }
    }

    function cloneRandom(pHead) {
      var current = pHead;
      while (current) {
        var cloneNode = current.next;
        if (current.random) {
          cloneNode.random = current.random.next;
        } else {
          cloneNode.random = null;
        }
        current = cloneNode.next;
      }
    }

    function reconnetNodes(pHead) {
      var cloneHead = pHead.next;
      var cloneNode = pHead.next;
      var current = pHead;
      while (current) {
        current.next = cloneNode.next;
        current = cloneNode.next;
        if (current) {
          cloneNode.next = current.next;
          cloneNode = current.next;
        } else {
          cloneNode.next = null;
        }
      }
      return cloneHead;
    }

2.二叉搜刮树转换为双向链表

输入一棵二叉搜刮树,将该二叉搜刮树转换成一个排序的双向链表。请求不能建立任何新的结点,只能调解树中结点指针的指向。

思绪

1.排序的双向链表-中序遍历二叉树

2.纪录链表的末了一个节点

3.每次遍历:设置树节点的left和链表的right举行链接,链接胜利后当前节点成为链表的末端节点,并返回。

代码

       function Convert(pRootOfTree) {
      var lastNode = null;
      lastNode = convertToList(pRootOfTree, lastNode);
      while (lastNode && lastNode.left) {
        lastNode = lastNode.left;
      }
      return lastNode;
    }

    function convertToList(treeNode, lastNode) {
      if (!treeNode) {
        return null;
      }
      if (treeNode.left) {
        lastNode = convertToList(treeNode.left, lastNode);
      }
      treeNode.left = lastNode;
      if (lastNode) {
        lastNode.right = treeNode;
      }
      lastNode = treeNode;
      if (treeNode.right) {
        lastNode = convertToList(treeNode.right, lastNode);
      }
      return lastNode;
    }

3.字符串的分列

输入一个字符串,按字典序打印出该字符串中字符的一切分列。比方输入字符串abc,则打印出由字符a,b,c所能分列出来的一切字符串abc,acb,bac,bca,cab和cba。

输入一个字符串,长度不凌驾9(可能有字符反复),字符只包含大小写字母。

思绪

1.把字符串分红两部分,第一个字符和背面的字符
2.全部字符串的全分列即是:第一个字符+背面字符的全分列,第一个字符和背面的字符诸葛交流。

第一个字符+背面字符的全分列3.除了第一个字符其他字符的全分列即是:第二个字符+背面字符的全分列。

3.递归,纪录一个当前节点的位置,该位置指向末了一个节点时纪录一次分列。

代码

    function Permutation(str) {
      var result = [];
      if (!str) {
        return result;
      }
      var array = str.split('');
      permutate(array, 0, result);
      result.sort();
      return [... new Set(result)];
    }

    function permutate(array, index, result) {
      if (array.length - 1 === index) {
        result.push(array.join(''));
      }
      for (let i = index; i < array.length; i++) {
        swap(array, index, i);
        permutate(array, index + 1, result);
        swap(array, i, index);
      }
    }

    function swap(arr, i, j) {
      [arr[i], arr[j]] = [arr[j], arr[i]];
    }
    原文作者:ConardLi
    原文地址: https://segmentfault.com/a/1190000018268218
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞