破解编码面试2.1从单链接列表中删除重复值javascript。

问题描述 投票:0回答:2
class LinkedListNode {
    constructor(value) {
        this.value = value;
        this.next = null;
    }
}

let head = new LinkedListNode("head");

let x = [1, 1, 1, 1, 4, 10, 10, 3, 10, 9, 5, 5, 5, 8];

for (let ele of x) {
    let y = new LinkedListNode(ele);
    let pointer = head;
    while (pointer.next != null) {
        pointer = pointer.next;
    }
    pointer.next = y;
}

谁能解释一下为什么下面的 "解决方案 "会导致一个无限循环?

let removeDup = function(sll) {
    let array = []
    let pointer = sll;
    while (pointer) {
        if (array.includes(pointer.value)){
        } else {
            array.push(pointer.value);
            sll.next = pointer;
            sll = sll.next;
        }
        pointer = pointer.next;
    }
}

似乎如果我

let pointer = sll.next;

let array = [sll.value]

那么它就能正常工作,但如果我按原样运行,它就会导致一个无限循环。我知道为什么它可能会产生一个链接列表,其中第一个值有两个重复,但我不明白为什么它会产生一个无限循环。另外,如果有人能给我指出正确的调试方向,我将感激不尽。

javascript algorithm infinite-loop singly-linked-list
2个回答
1
投票

看起来你最终定义了一个在 else 条件中引用自己的节点。

你可能正在寻找类似这样的东西。

class LinkedListNode {
    constructor(value) {
        this.value = value;
        this.next = null;
    }
}

let head = new LinkedListNode("head");

let x = [1, 1, 1, 1, 4, 10, 10, 3, 10, 9, 5, 5, 5, 8];

for (let ele of x) {
    let y = new LinkedListNode(ele);
    let pointer = head;
    while (pointer.next != null) {
        pointer = pointer.next;
    }
    pointer.next = y;
}

function removeDup(currentNode = sll) {
	const seen = {};
	let lastUnique;
	while (currentNode) {
		if (seen[currentNode.value]) {
			lastUnique.next = currentNode.next;
		} else {
			seen[currentNode.value] = true;
			lastUnique = currentNode;
		}
		currentNode = currentNode.next;
	}
}

removeDup(head);

let outputNode = head;
while (outputNode) {
	outputNode = outputNode.next;
	if (outputNode) {
		console.log(outputNode.value);
	}
}

0
投票
  1. 如何调查你的错误

你可以使用调试器,但对于像我这样的原始人,你也可以使用 console.log

  • 在无限循环的情况下,你要做的是挣脱束缚。
let count = 0
while (pointer && count++<5) {
  //whatever
}

即使你的算法失败了,你也会退出。

  • 输出您的变量

要有创意,在你认为合适的地方发送垃圾邮件控制台.日志。

while (pointer) {
  if (array.includes(pointer.value)){
    console.log('cached skip')
  } else {
    console.log('pointervalue', pointer.value)
    array.push(pointer.value);
    sll.next = pointer;
    sll = sll.next;
    console.log('sllendloop', sll)
  }
  pointer = pointer.next;
}
  1. 修复您的代码

注意:不要用数组来做缓存,因为它是O(n)的样子。

您可以使用集(O(1))代替

const removeDup = function(sll) {
  const dupes = new Set()
  let cur = { next: null }
  // you can also as you suggested initialize cur as sll
  // in which case you must mark it as "consumed" idem add the value to dupes
  let sllIter = sll
  while (sllIter) {
    if (dupes.has(sllIter.value)) {
      // early continue to avoid nesting else
      // subjective preference
      sllIter = sllIter.next
      continue
    }
    dupes.add(sllIter.value)
    // link our node to the currently being iterated node
    cur.next = sllIter;

    // advance our node
    cur = sllIter

    // advance iter
    sllIter = sllIter.next
  }
  return sll
}
const l = (value, next) => ({ value, next })
const sllStr = ({ value: a, next: b }) => b ? `${a} -> ${sllStr(b)}`: a
const sll = l(1, l(1, l(2, l(1, l(2, l(3))))))
console.log(sllStr(removeDup(sll))) // 1 -> 2 -> 3

0
投票

你或许可以写一个微型关联列表库。这里有一个带功能描述的库。

  • toList : 将一个数组转换为一个列表。
  • foldList : 类似于reduce。取一个 list,一个函数和一个累加器。
  • sum 取一个 list,并给出它的总和 :)
  • prt :漂亮地打印一个列表
  • nub :从列表中删除重复的内容。

function List(e){
  this.data = e;
  this.next = null;
}

List.fromArray = function([a,...as]){
                   var h = new List(a),
                       t = as.reduce((l,e) => [l[0],l[1].next = new List(e)], [h,h]);
                   return t[0];
                 };
List.prototype.fold = function (f,a){
                        var newa = f(a, this.data);
                        return this.next ? this.next.fold(f, newa)
                                         : newa
                      };
List.prototype.log = function(){
                       return this.fold((a,e) => a + e + " -> ", "") + "null";
                     };
List.prototype.nub = function(){
                       var o = this.fold((a,e) => (a[e] = e, a), {}),
                           a = Object.values(o);
                       return List.fromArray(a);
                     }

var arr = [1, 1, 1, 1, 4, 10, 10, 3, 10, 9, 5, 5, 5, 8],
    lst = List.fromArray(arr),
    sum = l => l.fold((a,e) => a + e, 0), // just for fun
    res = lst.nub().log();

console.log(res);

nub 是O(n)。

© www.soinside.com 2019 - 2024. All rights reserved.