LeetCode刷题笔记3——链表

文章目录

  • LeetCode刷题笔记3——链表
    • 反转链表
    • 环形链表
    • 合并两个有序链表
    • 移除链表元素
    • 删除链表中的重复元素
    • 参考资料

LeetCode刷题笔记3——链表

反转链表

题目

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

示例

示例1

输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]

示例2

输入:head = [1,2]
输出:[2,1]

示例3

输入:head = []
输出:[]
  • 链表中节点的数目范围是 [0, 5000]
  • -5000 <= Node.val <= 5000

迭代

class Solution2 {
	public ListNode reverseList(ListNode head) {
		ListNode currNode = head;
		ListNode preNode = null;//需要多设置一个空结点
		while (currNode != null) {
			ListNode nextNode = currNode.next;
			currNode.next = preNode;
			//当前结点的下一个结点为前一个结点
			preNode = currNode;
			//前一个结点后移
			currNode = nextNode;
			//当前结点后移
		}
		return preNode;
	}
}

递归

递归的两个条件:

  1. 终止条件是当前节点或者下一个节点==null
  2. 在函数内部,改变节点的指向,也就是 head 的下一个节点指向 head 递归函数那句head.next.next = head

LeetCode刷题笔记3——链表_第1张图片

class Solution {
    public ListNode reverseList(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        ListNode newHead = reverseList(head.next);
        head.next.next = head;
        head.next = null;
        return newHead;
    }
}

环形链表

题目

给你一个链表的头节点 head ,判断链表中是否有环。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。

如果链表中存在环 ,则返回 true 。 否则,返回 false 。

示例

示例 1:

输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。

示例 2:

输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。

示例 3:

输入:head = [1], pos = -1
输出:false
解释:链表中没有环。

代码

使用集合

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public boolean hasCycle(ListNode head) {
        Set<ListNode> nodes = new HashSet<>();
        while(head.next!=null){
            if(!nodes.add(head)){//集合中有重复节点则返回false
                return true;
            }
            head = head.next;
        }
        return false;
    }
}

使用快慢指针

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public boolean hasCycle(ListNode head) {
        ListNode slow = head;
        ListNode fast = head;
        while(fast != null && fast.next !=null){
            fast = fast.next.next;
            slow = slow.next;
            if(fast==slow) return true;
        }//快慢结点,空间复杂度为O(1)
        return false;
        
    }
}

合并两个有序链表

题目

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

示例

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-25mh17Fv-1647330065904)(https://assets.leetcode.com/uploads/2020/10/03/merge_ex1.jpg)]

示例 1:

输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]
示例 2:

输入:l1 = [], l2 = []
输出:[]
示例 3:

输入:l1 = [], l2 = [0]
输出:[0]

递归实现

/**
 * 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 mergeTwoLists(ListNode l1, ListNode l2) {
        if (l1 == null) {
            return l2;
        } else if (l2 == null) {
            return l1;
        } else if (l1.val < l2.val) {
            l1.next = mergeTwoLists(l1.next, l2);
            return l1;
        } else {
            l2.next = mergeTwoLists(l1, l2.next);
            return l2;
        }
    }
}

移除链表元素

题目

给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点

示例

LeetCode刷题笔记3——链表_第2张图片

示例 1:

输入:head = [1,2,6,3,4,5,6], val = 6
输出:[1,2,3,4,5]

示例 2:

输入:head = [], val = 1
输出:[]

示例 3:

输入:head = [7,7,7,7], val = 7
输出:[]

提示:

列表中的节点数目在范围 [0, 10^4] 内
1 <= Node.val <= 50
0 <= val <= 50

代码

/**
 * 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 removeElements(ListNode head, int val) {
    	ListNode firstListNode = new ListNode(-1,head);//虚结点
    	ListNode temp = firstListNode;
    	while(temp.next !=null) {//下一个结点不为空
    		if (temp.next.val == val) {
    			temp.next = temp.next.next;
			}else {
				temp = temp.next;
			}
    		
    	}
    	return firstListNode.next;//虚结点的下一个结点即为头结点
    }
}

删除链表中的重复元素

题目

给定一个已排序的链表的头 head删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表

示例

示例 1:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-87lcSdGF-1647330065905)(https://assets.leetcode.com/uploads/2021/01/04/list1.jpg)]

输入:head = [1,1,2]
输出:[1,2]

示例 2:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vrwwXmuw-1647330065906)(https://assets.leetcode.com/uploads/2021/01/04/list2.jpg)]

输入:head = [1,1,2,3,3]
输出:[1,2,3]

提示:

链表中节点数目在范围 [0, 300] 内
-100 <= Node.val <= 100
题目数据保证链表已经按升序 排列

代码

/**
 * 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 deleteDuplicates(ListNode head) {
		if (head == null) {
			return head;
		}
		ListNode currentNode = head;
		while(currentNode.next != null) {
			if (currentNode.val ==currentNode.next.val) {
				currentNode.next = currentNode.next.next;
                //重复元素都是连续的
			}else {
				currentNode = currentNode.next;
			}
		}
		return head;
	}
}

参考资料

链接:https://leetcode-cn.com/problems/reverse-linked-list/solution/dong-hua-yan-shi-206-fan-zhuan-lian-biao-by-user74/

链接:https://leetcode-cn.com/problems/linked-list-cycle

链接:https://leetcode-cn.com/problems/merge-two-sorted-lists

链接:https://leetcode-cn.com/problems/remove-linked-list-elements

链接:https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list

你可能感兴趣的:(#,leetcode,链表,leetcode,算法)