链表
1、删除链表中的节点
请编写一个函数,使其可以删除某个链表中给定的(非末尾)节点,你将只被给定要求被删除的节点。
现有一个链表 -- head = [4,5,1,9],它可以表示为:
示例 1:
输入: head = [4,5,1,9], node = 5
输出: [4,1,9]
解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9.
示例 2:
输入: head = [4,5,1,9], node = 1
输出: [4,5,9]
解释: 给定你链表中值为 1 的第三个节点,那么在调用了你的函数之后,该链表应变为 4 -> 5 -> 9.
说明:
-
链表至少包含两个节点。
-
链表中所有节点的值都是唯一的。
-
给定的节点为非末尾节点并且一定是链表中的一个有效节点。
-
不要从你的函数中返回任何结果。
解题思路
纠错:第一眼,我看到输入是一个数组,以为要整个出来,后来才发现Leetcode的题目是.....。不是代码完整写出的。思路: 将删除节点的值等于下一个节点的,然后将这个节点的下节点等于下下个节点。于是这个节点就被完美的干掉了
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public void deleteNode(ListNode node) {
node.val = node.next.val;
node.next = node.next.next;
}
}
2、删除链表的倒数第N个节点
给定一个链表,删除链表的倒数第 *n *个节点,并且返回链表的头结点。
示例:
给定一个链表: 1->2->3->4->5, 和 n = 2.
当删除了倒数第二个节点后,链表变为 1->2->3->5.
说明:
给定的 n 保证是有效的。
进阶:
你能尝试使用一趟扫描实现吗?
解题思路
纠错 起先我以为可以立个 flag,然后进行while循环,内购置一个条件,如果满足,就是这个,然后通过上一题删除法,干掉它,后来发现。错的很离谱思路 可以先考虑如果 n > 链表长度的时候,那么就不得行 再考虑 n = 链表长度的时候,那么就干掉第一个了 然后考虑如果小于的话,可以弄个 pre, end 节点,两者相差 n,如果end到了 null,那么 pre的下一个节点就是要删除的那个。
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode pre, end;
pre = head;
end = head;
for(int i = 0; i < n; i++)
{
end = end.next;
}
if(end == null)
{
pre = pre.next;
return pre;
}
while(end.next != null)
{
pre = pre.next;
end = end.next;
}
pre.next = pre.next.next;
return head;
}
}
3、反转链表
反转一个单链表。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
进阶:
你可以迭代或递归地反转链表。你能否用两种方法解决这道题?
迭代思路 可以考虑这样定义 一个pre = null 然后将 cur 指向的一个个转移,指向 pre
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
ListNode pre = null;
ListNode cur = head;
while(cur != null)
{
// 1 2 3 4 5 null
ListNode temp = cur.next;
cur.next = pre; // 1 null
pre = cur; // cur -> 1 pre -> 1
cur = temp;
}
return pre;
}
}
递归思路 如果没有到最后就一直 就是递归 + 回溯
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
if(head == null || head.next == null)
{
return head;
}
else{
ListNode pre = reverseList(head.next); 7 6 pre 根节点
head.next.next = head;
head.next = null;
return pre;
}
}
}
4、将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
思路 先创建一个节点。然后比较两者,小者接 直到一方 null了,直接把尾巴接到另一方上去 返回 l3.next 原因,干掉初始化那个
示例:
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode l3 = new ListNode(10);
ListNode cur = l3;
while(l1 != null && l2!= null)
{
if(l1.val <= l2.val)
{
cur.next = l1;
l1 = l1.next;
}
else {
cur.next = l2;
l2 = l2.next;
}
cur = cur.next;
}
if(l1 == null)
{
cur.next = l2;
}
else {
cur.next = l1;
}
return l3.next;
}
}