数据结构之链表

链表
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;
 }
 }
posted @ 2020-02-15 15:06  小喵钓鱼  阅读(144)  评论(0编辑  收藏  举报