public ListNode removeNthFromEnd(ListNode head, int n){ ListNode dummyNode = new ListNode(0); dummyNode.next = head; ListNode fastIndex = dummyNode; ListNode slowIndex = dummyNode; //只要快慢指针相差 n 个结点即可 for (int i = 0; i < n ; i++){ fastIndex = fastIndex.next; } while (fastIndex.next != null){ fastIndex = fastIndex.next; slowIndex = slowIndex.next; } //此时 slowIndex 的位置就是待删除元素的前一个位置。 //具体情况可自己画一个链表长度为 3 的图来模拟代码来理解 slowIndex.next = slowIndex.next.next; return dummyNode.next;和 public ListNode removeNthFromEnd(ListNode head, int n) { ListNode s = new ListNode(-1,head); ListNode p1 = s; ListNode p2 = s; for(int i = 0; i < n+1; i++) { p2 = p2.next; } while(p2 != null){ //循环结束p2指向null p1=p1.next; p2=p2.next; } p1.next=p1.next.next; return s.next; }有哪里不同
时间: 2024-04-01 11:31:57 浏览: 80
这两段代码实现的功能相同,都是删除链表中倒数第 n 个结点。它们的不同之处在于实现细节。第一个代码使用两个指针,一个快指针,一个慢指针,快指针先走 n 步,然后快慢指针一起走,当快指针走到链表末尾时,慢指针指向的结点就是要删除的结点的前一个结点,然后直接删除即可。第二个代码也是使用两个指针,但是在快指针先走 n 步之后,它们同时开始移动,当快指针走到链表末尾时,慢指针指向的结点就是要删除的结点的前一个结点,然后直接删除即可。第二个代码在定义链表的时候多了一个虚拟头结点,这样可以避免删除头结点的特殊情况。
相关问题
public ListNode reverseBetween (ListNode head, int m, int n) { //设置虚拟头节点 ListNode dummyNode = new ListNode(-1); dummyNode.next =head; ListNode pre = dummyNode; for(int i=0;i<m-1;i++){ pre = pre.next; } ListNode cur = pre.next; ListNode Cur_next ; for(int i=0;i<n-m;i++){ Cur_next = cur.next; cur.next = Cur_next.next; Cur_next .next = pre.next; pre.next = Cur_next ; } return dummyNode.next; }
这段代码是一个反转链表中指定范围节点的方法。让我来解释一下代码的逻辑:
首先,代码创建了一个名为 `dummyNode` 的虚拟头节点,并将其指向原始链表的头节点 `head`。
```java
ListNode dummyNode = new ListNode(-1);
dummyNode.next = head;
```
然后,代码定义了一个指向虚拟头节点的指针 `pre`,并将其移动到要反转的起始位置的前一个节点。
```java
ListNode pre = dummyNode;
for (int i = 0; i < m - 1; i++) {
pre = pre.next;
}
```
接着,代码定义了一个指向当前节点的指针 `cur`,并将其初始化为 `pre` 的下一个节点。
```java
ListNode cur = pre.next;
```
然后,代码开始执行实际的反转操作。使用一个循环来反转从位置 `m` 到位置 `n` 的节点。
```java
for (int i = 0; i < n - m; i++) {
ListNode cur_next = cur.next;
cur.next = cur_next.next;
cur_next.next = pre.next;
pre.next = cur_next;
}
```
在每次循环中,首先保存当前节点 `cur` 的下一个节点 `cur_next`。然后,将当前节点的 `next` 指针指向 `cur_next` 的下一个节点,实现节点的删除。接着,将 `cur_next` 的 `next` 指针指向 `pre` 的下一个节点,实现节点的插入。最后,将 `pre` 的 `next` 指针指向 `cur_next`,完成节点的反转。循环执行直到达到指定范围的节点。
最后,代码返回虚拟头节点 `dummyNode` 的下一个节点,即反转后的链表头节点。
```java
return dummyNode.next;
```
这段代码的作用是反转链表中从位置 `m` 到位置 `n` 的节点,并返回反转后的链表的头节点。
把我注释下列代码/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode() {} * ListNode(int val) { this.val = val; } * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */ class Solution { public ListNode partition(ListNode head, int x) { ListNode small = new ListNode(0); ListNode smallHead = small; ListNode large = new ListNode(0); ListNode largeHead = large; while (head != null) { if (head.val < x) { small.next = head; small = small.next; } else { large.next = head; large = large.next; } head = head.next; } large.next = null; small.next = largeHead.next; return smallHead.next; } }
这段代码是一个将链表按照给定值x分割的函数。注释如下:
```java
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
// 将链表按照给定值x分割
public ListNode partition(ListNode head, int x) {
// 创建两个虚拟节点small和large,分别表示小于x和大于等于x的链表部分
ListNode small = new ListNode(0);
ListNode smallHead = small;
ListNode large = new ListNode(0);
ListNode largeHead = large;
// 遍历链表中的每个节点
while (head != null) {
// 如果节点的值小于x,则将节点连接到small链表的末尾,并更新small指针
if (head.val < x) {
small.next = head;
small = small.next;
}
// 如果节点的值大于等于x,则将节点连接到large链表的末尾,并更新large指针
else {
large.next = head;
large = large.next;
}
// 遍历下一个节点
head = head.next;
}
// 将large链表的末尾指向null,避免出现环形链表
large.next = null;
// 将small链表的末尾连接到large链表的头部,得到最终的分割链表
small.next = largeHead.next;
// 返回small链表的头部作为结果
return smallHead.next;
}
}
```
注释的作用是解释代码的功能和实现思路,便于其他开发人员理解和维护代码。
阅读全文