JS実装依存のアルゴリズムリスト
なぜJS
JSは、関数型プログラミングで、より便利に実現しています。そして今、ツールをデバッグすることは非常に便利でもあります。唯一のブラウザの可能性があるため。
Jsの多くの優れた特性、配列の特に操作があります。正規表現のサポートがあり、など。
一般的なアルゴリズムを記述するだけでは十分である...最も重要なのは簡単です!
背景
アルゴリズムのコースを購入する時にオタクが。集中アルゴリズム勉強を取るつもり!
でLeetCode、リストのトピックについて、下記の難易度によって並べ替えられていますが行なわ。
// 定义一个 ListNode
function ListNode(val) {
this.val = val;
this.next = null;
}
リバースリスト
- ヘッド軸において、順次各ノードを通過します。
- 2つのノードが、それぞれ、前及び記録後の両方に設けられていることに注意してください
// 反转链表
let reverseList = function(head) {
let pre = null;
let post = null;
while (head !== null) {
post = head.next;
head.next = pre;
pre = head;
head = post;
}
return pre;
};
チェーンリングがあるかどうかを決定します
1アイデアのセットを使用します
- そこには、リングを説明するために繰り返されている場合、セットに設定されているデータを挿入します
// 判断是否有环,有返回入口节点,无返回null
let detectCycle = function(head) {
let set = new Set();
while (head != null) {
if (set.has(head)) {
return head;
} else {
set.add(head)
head = head.next;
}
}
return null;
};
2速ポインタのアイデア
- ポインタのポインタ低速チェイス、キャッチリング、説明されていないキャッチリングが記載されている場合
- アナロジーは、実行することができ、それは100百メートルであればストレート、高速と低速の人は人に会うことはできませんが、5キロ長距離走場合、発生します。
なぜ二回の高速ポインタのポインタ低速ではなく、それの他の高倍数としてですか?
- まず、他の離散的な点ではなく、連続的な点へのポインタ
- 彼らはできるだけ早く会いたい、そして私たちは、彼らは非常によく似加速できるようにする必要があります
- もちろん、存在し、倍以上の最初の出会いがあるかもしれない例外があります。
- あなたは下の表を見ることができ、テーブル内のデータが示す
环大小为4的环
開始からの距離- しかし、リングのサイズを事前に知ることができないので、二回より安全です。
スピード1 | 2の速度 | 3の速度 | 4の速度 |
---|---|---|---|
1 | 2 | 3 | 0 |
2 | 4 | 2(MET) | 0 |
3 | 2 | 0 | |
0 | 0(MET) | (ミート) |
// 判断是否有环,有返回入口节点,无返回null
var hasCycle = function(head) {
// 如果就1个节点,且next为空
if (head.next === null) {
return false;
}
let fast = head.next.next;
let slow = head.next;
while (fast !== null) {
if (fast === slow) {
return true;
}
slow = slow.next;
if (fast.next === null) {
return false;
}
fast = fast.next.next;
}
return false;
};
開環におけるリングノード
- 限りリターンがその遭遇される単語のセットを有する開環におけるリングノード、
- トラブルのあなたはポインタの速度を使用する場合は、多くの、二回通過する必要性
- 最初のトラバーサルは、満たすために最初の位置を取得します
- 次いで与える開環を横切ります
// 判断是否有环,有返回入口节点,无返回null
var detectCycle = function(head) {
var set = new Set();
while (head != null) {
if (set.has(head)) {
return head;
} else {
set.add(head)
head = head.next;
}
}
return null;
};
私はリングに口を得るために、ポインタの速度を使用する方法を長い間考えた
問題のいくつかについて考え、当時と
仮定入环前的距离为 M
し、环的大小 K
それは、思考することによって得ることができる
回数は、満たすために行くために初めて
M + K-(M%K)
実際には、これは、チェースの簡単な質問ですが、コードを使用して、いくつかのトラブルを達成するために
- まず、リング外の事を考慮していない、唯一のリングで検討し、二人の追跡
- 二人はその時に少しの前で速くよりもリングでその時遅く、その後、より速く、より低速での出会いに長い時間を回復するために、一つの方向に実行されています
△x = △v * t
アソシエイト、時針と分針は一日何回も会い、同じ方法を用いて計算することができる。22回
上記の式に戻ります
K - (M%K)
事実、取得するために、リングに、高速ポインタ位置をリングに入るときポインタが遅いです- 2間の速度差は1であるため、そして、リング徒歩圏内に2つのポインタがあります
K - (M%K)
- Mと相まって、ポインタが距離を移動するために直線的に遅いです
Kに設定され、リストを逆転しました
グループとしてKを使用すると、リンクリストLeetcodeを逆転
- JSを聞かせて使用してみてください
- コードは少し、具体的なコメントを見て、複雑になっています
- リストをグループ化することによって分割されていないの右側に、ポイントオフの中間点を左に回すことにします
- 反転の第1のセットは留意すべきである、第1のオブジェクトの記録ノードの結果を使用
- 最後のグループを満たすKかどうかを決定するために、kは再び反転します
- ノードグループは、主に約2つのノードを予約する前と後に反転され、最初は空である逆に覚え
// 反转链表
let reverseList = function(headTemp) {
let head = headTemp;
let pre = null;
let post = null;
while (head !== null) {
post = head.next;
head.next = pre;
pre = head;
head = post;
}
return pre;
};
let getEndNode = function(head, k) {
for (let i = 0; i < k - 1; i++) {
if (head == null) {
return false;
}
// 这里的head,可能返回null,当i=k-1,但是head.next == null
head = head.next;
}
return head;
}
// K 个元素为一组交换
// 需要3个节点记录,并且以head为轴,进行处理
let reverseKGroup = function(head, k) {
let first = null;
let pre = null;
while (head != null) {
let start = head;
let end = getEndNode(head, k);
// end 为false 或则 null,说明剩下的不足k
if (end === false || end === null) {
return first;
} else {
head = end.next;
}
end.next = null;
reverseList(start)
start.next = head;
// 第一次反转时,pre是null
if (pre != null) {
pre.next = end;
} else {
// 取得第一组的反转后的第一个
first = end;
}
// pre指向start,作为下一次分组的开始
pre = start;
}
return first;
}