Подход 1: рекурсия
Интуиция
Самая простая стратегия здесь — использовать рекурсию. Убедитесь, что узлы p
и q
не являются узлами None
, и их значения равны. Если все проверки в порядке, сделайте то же самое для дочерних узлов рекурсивно.
JavaScript
/** * Definition for a binary tree node. * function TreeNode(val, left, right) { * this.val = (val===undefined ? 0 : val) * this.left = (left===undefined ? null : left) * this.right = (right===undefined ? null : right) * } */ /** * @param {TreeNode} p * @param {TreeNode} q * @return {boolean} */ var isSameTree = function(p, q) { if (p === null && q === null) return true; if (p === null || q === null) return false; if (p.val !== q.val) { return isSameTree(p.right, q.right) && isSameTree(p.left, q.left); } };
Подход 2: Итерация
Интуиция
Начните с корня, а затем на каждой итерации извлекайте текущий узел из очереди. Затем выполните те же проверки, что и в подходе 1:
p
иp
неNone
,p.val
равноq.val
,
и если проверки в порядке, нажмите дочерние узлы.
Ява
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ class Solution { public boolean isSameTree(TreeNode p, TreeNode q) { // p and q are both null if (p == null && q == null) return true; // one of p and q is null if (q == null || p == null) return false; if (p.val != q.val) return false; return isSameTree(p.right, q.right) && isSameTree(p.left, q.left); } }
массив JS по умолчанию уже представляет собой такую структуру: push()
, pop()
, shift()
, unshift()
, а также стандартный доступ к индексу должны предоставить вам все необходимые инструменты.
В JavaScript есть встроенная поддержка операций deque через класс/прототип Array: push, pop, shift, unshift.
Если вы все еще хотите написать свою собственную реализацию, вы можете использовать двусвязный список, где вам просто нужны два «указателя». Следует сказать, что в JavaScript мы говорим не об указателях, а об объектах. Переменные или свойства, которые получают объект в качестве значения, фактически являются ссылками в JavaScript.
В качестве альтернативы вы можете выбрать круговой массив. Поскольку в JavaScript стандартные массивы не обязательно являются последовательными массивами, как, например, в случае C, вам не нужно использовать для этого экземпляр Array. Подойдет простой объект (или карта).
Итак, вот две возможные реализации:
Двусвязный список
class Deque {
constructor() {
this.front = this.back = undefined;
}
addFront(value) {
if (!this.front) this.front = this.back = { value };
else this.front = this.front.next = { value, prev: this.front };
}
removeFront() {
let value = this.peekFront();
if (this.front === this.back) this.front = this.back = undefined;
else (this.front = this.front.prev).next = undefined;
return value;
}
peekFront() {
return this.front && this.front.value;
}
addBack(value) {
if (!this.front) this.front = this.back = { value };
else this.back = this.back.prev = { value, next: this.back };
}
removeBack() {
let value = this.peekBack();
if (this.front === this.back) this.front = this.back = undefined;
else (this.back = this.back.next).back = undefined;
return value;
}
peekBack() {
return this.back && this.back.value;
}
}
// demo
let deque = new Deque;
console.log(deque.peekFront()); // undefined
deque.addFront(1);
console.log(deque.peekBack()); // 1
deque.addFront(2);
console.log(deque.removeBack()); // 1
deque.addFront(3);
deque.addFront(4);
console.log(deque.peekBack()); // 2
deque.addBack(5);
deque.addBack(6);
console.log(deque.peekBack()); // 6
console.log(deque.removeFront()); // 4
console.log(deque.removeFront()); // 3
console.log(deque.removeFront()); // 2
console.log(deque.removeFront()); // 5
console.log(deque.removeFront()); // 6
console.log(deque.removeFront()); // undefined
Круговой «Массив»
class Deque {
constructor() {
this.data = {}; // Or Array, but that really does not add anything useful
this.front = 0;
this.back = 1;
this.size = 0;
}
addFront(value) {
if (this.size >= Number.MAX_SAFE_INTEGER) throw "Deque capacity overflow";
this.size++;
this.front = (this.front + 1) % Number.MAX_SAFE_INTEGER;
this.data[this.front] = value;
}
removeFront() {
if (!this.size) return;
let value = this.peekFront();
this.size--;
delete this.data[this.front];
this.front = (this.front || Number.MAX_SAFE_INTEGER) - 1;
return value;
}
peekFront() {
if (this.size) return this.data[this.front];
}
addBack(value) {
if (this.size >= Number.MAX_SAFE_INTEGER) throw "Deque capacity overflow";
this.size++;
this.back = (this.back || Number.MAX_SAFE_INTEGER) - 1;
this.data[this.back] = value;
}
removeBack() {
if (!this.size) return;
let value = this.peekBack();
this.size--;
delete this.data[this.back];
this.back = (this.back + 1) % Number.MAX_SAFE_INTEGER;
return value;
}
peekBack() {
if (this.size) return this.data[this.back];
}
}
// demo
let deque = new Deque;
console.log(deque.peekFront()); // undefined
deque.addFront(1);
console.log(deque.peekBack()); // 1
deque.addFront(2);
console.log(deque.removeBack()); // 1
deque.addFront(3);
deque.addFront(4);
console.log(deque.peekBack()); // 2
deque.addBack(5);
deque.addBack(6);
console.log(deque.peekBack()); // 6
console.log(deque.removeFront()); // 4
console.log(deque.removeFront()); // 3
console.log(deque.removeFront()); // 2
console.log(deque.removeFront()); // 5
console.log(deque.removeFront()); // 6
console.log(deque.removeFront()); // undefined
Методы возвращают undefined
при попытке получить значение из пустой очереди.
Я предлагаю добавить delete
в методы удаления, чтобы не было утечки памяти.