160交差リスト
交差開始ノード2つのリストを見つけるためのプログラムを書きます。
以下の二つのリスト:
交差点ノードC1で始まります。
例1:
输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
输出:Reference of the node with value = 8
输入解释:相交节点的值为 8 (注意,如果两个列表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。
例2:
输入:intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
输出:Reference of the node with value = 2
输入解释:相交节点的值为 2 (注意,如果两个列表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [0,9,1,2,4],链表 B 为 [3,2,4]。在 A 中,相交节点前有 3 个节点;在 B 中,相交节点前有 1 个节点。
例3:
输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
输出:null
输入解释:从各自的表头开始算起,链表 A 为 [2,6,4],链表 B 为 [1,5]。由于这两个链表不相交,所以 intersectVal 必须为 0,而 skipA 和 skipB 可以是任意值。
解释:这两个链表不相交,因此返回 null。
注意:
- 二つのリストのない交差点がない場合は、返されます
null
。 - 結果に戻した後、二つのリストはまだ元の構造を維持しなければなりません。
- 全体のリストには周期構造が存在しないと仮定することができます。
- プログラム(O会いしてみN-)時の複雑さ、そして唯一のO(1)メモリを。
ポインタの速度を設定します。
public ListNode getIntersectionNode (ListNode headA, ListNode headB) {
if (headA == null || headB == null) return null;
ListNode p1 = headA;
ListNode p2 = headB;
while (p1 != p2) {
if (p1 == null) p1 = headB;
else p1 = p1.next;
if (p2 == null) p2 = headA;
else p2 = p2.next;
}
return p1;
}
206反転リスト
単独リンクリストを逆にします。
例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
高度:
あなたは、反復逆転または再帰的に一覧表示することができます。次の2つの方法でこの問題を解決することはできますか?
再帰:
public ListNode reverseList(ListNode head) {
if(head == null || head.next == null){
return head;
}
ListNode rest = head.next;
ListNode newHead = reverseList(rest);
rest.next = head;
head.next = null;
return newHead;
}
反復法:
public ListNode reverseList(ListNode head) {
ListNode prev = null;
ListNode cur = head;
while(cur != null){
ListNode next = cur.next;
cur.next = prev;
prev = cur;
cur = next;
}
return prev;
}
21.組み合わせた2つの命じたリスト
2は、新たなソートされたリストとリターンにリストを命じました。新しいリストは、二つのリストで構成与えられたモザイク内のすべてのノードです。
例:
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
ダブルポインタのアイデア
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if(l1 == null) return l2;
if(l2 == null) return l1;
if(l1.val < l2.val){
l1.next = mergeTwoLists(l1.next,l2);
return l1;
}else{
l2.next = mergeTwoLists(l1,l2.next);
return l2;
}
}
83.ソートに繰り返し要素のリストを削除します。
各要素は1回だけ発生するようにソートされたリストを考えると、すべての重複要素を削除します。
例1:
输入: 1->1->2
输出: 1->2
例2:
输入: 1->1->2->3->3
输出: 1->2->3
ノートの境界条件の次の繰り返し。
public ListNode deleteDuplicates(ListNode head) {
ListNode cur = head;
while(cur != null && cur.next != null){
if(cur.val == cur.next.val)
cur.next = cur.next.next;
else
cur = cur.next;
}
return head;
}
19.相互のN個のノードのリストを削除
リストを考えると、リストの逆数を削除し、n個のノードをヘッドノードがリストを返します。
例:
给定一个链表: 1->2->3->4->5, 和 n = 2.
当删除了倒数第二个节点后,链表变为 1->2->3->5.
説明:
与えられたnは有効であることが保証されています。
高度:
あなたはそれを達成するために、1つのパスを使用しようとすることができますか?
ダミーノード設定、ステップN + 1を手放す、この時点でダミーノード1とノードだけダム2をダミーノード2、及び1及び2つのダミーノードはダミーノード間完了チェーン1まで一緒に移動するダミーノードを設定n個のノード間、およびダミーノードNのノード2を介して最後から二番目を削除します。
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode first = dummy;
for (int i = 1; i <= n + 1;i++){
first = first.next;
}
ListNode second = dummy;
while(first != null){
first = first.next;
second = second.next;
}
second.next = second.next.next;
return dummy.next;
}
234回文リスト
リストは回文であるかどうかを判断するためにリストを作成します。
例1:
输入: 1->2
输出: false
例2:
输入: 1->2->2->1
输出: true
高度:
あなたはこの問題を解決するためにO(n)の時間計算量とO(1)スペースの複雑さを使用することができますか?
ポインタ設定速度、それぞれ1及び2の移動速度。ポインタは左の正中央の(ノードの偶数の場合)または(奇数ノードの数の場合)にリンクされたリストの速い尾、低速の中央にポインタに到達すると、その後、ポインタは、遅い後退に反転されます遅いリスト先頭ポインタ、と平等のために、その後によるノードの比較。
public boolean isPalindrome (ListNode head) {
if (head == null || head.next == null) return true;
ListNode slow = head;
ListNode fast = head.next;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
slow = slow.next;
slow = reverse(slow);
while (slow != null) {
if (head.val == slow.val) {
head = head.next;
slow = slow.next;
} else
return false;
}
return true;
}
private ListNode reverse (ListNode head) {
ListNode newHead = null;
while (head != null) {
ListNode nextNode = head.next;
head.next = newHead;
newHead = head;
head = nextNode;
}
return newHead;
}
リンクされたリスト内のスイッチングノード24二十から二
隣接ノードとのリストのペアごとの交換を考えると、交換にリストを返します。
あなたは、単に内部ノードの値を変更することはできませんが、実際のノード交換する必要があります。
例:
给定 1->2->3->4, 你应该返回 2->1->4->3.
ダミーノード設定、(なぜなら必要二十から二スイッチングノードの)サイクル条件は、ポインタ2の動きの速さに注意してください。
public ListNode swapPairs (ListNode head) {
ListNode dummy = new ListNode(-1);
dummy.next = head;
ListNode pre = dummy;
while (pre.next != null && pre.next.next != null) {
ListNode l1 = pre.next;
ListNode l2 = pre.next.next;
l1.next = l2.next;
l2.next = l1;
pre.next = l2;
pre = l1;
}
return dummy.next;
}
445二つの数IIを追加します
与えられた二つの非空の二つの非負の整数を表すためにリストを。ビットの最大数は、リストの開始位置に配置されています。彼らは、各ノードは、単一の数字を格納します。2つの数字が一緒に新しいリストを返します。
あなたは数字0に加えて、これらの二つの数字がゼロで始まっていますことを仮定してもよいです。
高度:
入力リストを変更することができない場合はどのように対処するには?言い換えれば、あなたは、リスト内のノードを反転することはできません。
例:
输入: (7 -> 2 -> 4 -> 3) + (5 -> 6 -> 4)
输出: 7 -> 8 -> 0 -> 7
リストの構造は、値のリストを格納するために、スタックと、(反転リスト)を変更することはできないので、逆に出力を行うことができます。
従来の考え方によれば、コード・ロジック部分を書き込むための追加。
public ListNode addTwoNumbers (ListNode l1, ListNode l2) {
Stack<Integer> l1Stack = listNodetoStack(l1);
Stack<Integer> l2Stack = listNodetoStack(l2);
int carry = 0;
ListNode head = new ListNode(-1);
while (!l1Stack.isEmpty() || !l2Stack.isEmpty() || carry != 0) {
int x = l1Stack.isEmpty() ? 0 : l1Stack.pop();
int y = l2Stack.isEmpty() ? 0 : l2Stack.pop();
int sum = x + y + carry;
ListNode node = new ListNode(sum % 10);
carry = sum / 10;
node.next = head.next;
head.next = node;
}
return head.next;
}
private Stack<Integer> listNodetoStack (ListNode head) {
Stack<Integer> stack = new Stack<>();
while (head != null) {
stack.push(head.val);
head = head.next;
}
return stack;
}
725区切りのリスト
ヘッドノード所与のroot
リンクされたリストに分割リスト書き込む機能k
連続した部分を。
一部がヌルであってもよいことが、任意の2つの部分の間のギャップの長さは、複数のことはできません:各セクションの長さと同等でなければなりません。
それらがリストに表示される順番で出力k番目の一部である必要があり、上面部と長さがより大きいかまたは背面の長さに等しくなければなりません。
それは、リスト上の規則のリストを返します。
例:1-> 2-> 3-> 4、K = 5つの// 5件の結果[1]、[2]、[3]、[4]、NULL]
例1:
输入:
root = [1, 2, 3], k = 5
输出: [[1],[2],[3],[],[]]
解释:
输入输出各部分都应该是链表,而不是数组。
例如, 输入的结点 root 的 val= 1, root.next.val = 2, \root.next.next.val = 3, 且 root.next.next.next = null。
第一个输出 output[0] 是 output[0].val = 1, output[0].next = null。
最后一个元素 output[4] 为 null, 它代表了最后一个部分为空链表。
例2:
输入:
root = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], k = 3
输出: [[1, 2, 3, 4], [5, 6, 7], [8, 9, 10]]
解释:
输入被分成了几个连续的部分,并且每部分的长度相差不超过1.前面部分的长度大于等于后面部分的长度。
ヒント:
root
長さの範囲:[0, 1000]
。- 入力のサイズ範囲の各ノード:
[0, 999]
。 k
値の範囲:[1, 50]
。
K、商及び余りにより分割された第1の統計のリストの長さ:
- 残りは長鎖の数の最終結果を表します
- 「Sショートリストのそれぞれの代表的な長さ(結果リストの後部に設定)
- 短いリストリストに複数のノードよりも長いです
public ListNode[] splitListToParts (ListNode root, int k) {
ListNode cur = root;
int len = 0;
while (cur != null) {
cur = cur.next;
len++;
}
int mod = len % k;
int size = len / k;
cur = root;
ListNode[] ans = new ListNode[k];
for (int i = 0; cur != null && i < k; i++) {
ans[i] = cur;
int curSize = size + (mod-- > 0 ? 1 : 0);
for (int j = 0; j < curSize - 1; j++) {
cur = cur.next;
}
ListNode next = cur.next;
cur.next = null;
cur = next;
}
return ans;
}
328パリティリスト
ノードと、それぞれ単一のリスト、奇数および偶数行のすべてのノードを、指定されました。すなわち、ここでノード奇数および偶数パリティ・ノードではなくパリティノードの値より、ノード番号を指します。
アルゴリズムが完了したその場で使用してみてください。あなたのアルゴリズムの空間の複雑さは、(1)Oである必要があり、時間の複雑さは、ノードの数を合計する必要がありO(ノード)、ノードです。
例1:
输入: 1->2->3->4->5->NULL
输出: 1->3->5->2->4->NULL
例2:
输入: 2->1->3->5->6->4->7->NULL
输出: 2->3->6->7->1->5->4->NULL
説明:
- ノードのノードの奇数と偶数の相対的な順序を維持しなければなりません。
- ように奇数のノード、ノードの偶数である第2ノードと考え最初のノードのリスト。
、3つのポインタを設定するポインタ奇数とポインタが当然考えられる場合であっても、evenHead
一緒に奇数と偶数鎖結合リストのための補助的な役割を果たしています。
public ListNode oddEvenList (ListNode head) {
ListNode odd = head;
ListNode even = head.next;
ListNode evenHead = even;
while (even != null && even.next != null) {
odd.next = even.next;
odd = odd.next;
even.next = odd.next;
even = even.next;
}
odd.next = evenHead;
return head;
}