刷题笔记(链表)-12
Posted 康小庄
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了刷题笔记(链表)-12相关的知识,希望对你有一定的参考价值。
环形链表
题目地址:141. 环形链表 - 力扣(LeetCode) (leetcode-cn.com)
思路:递归
- 利用
Set
去重的特点,添加节点,如果节点重复,返回True - 递归直到结束
/**
* 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) {
HashSet<ListNode> set = new HashSet<>();
while(head!=null){
if (!set.add(head)){
return true;
}
head=head.next;
}
return false;
}
}
复杂度分析
-
时间复杂度:O(N),其中N是链表中的节点数。最坏情况下我们需要遍历每个节点一次
-
空间复杂度:O(N),其中N是链表中的节点数。主要为哈希表的开销,最坏情况下我们需要将每个节点插入到哈希表中一次
双指针法
参考官方题解学到了还可以这样解,还了解到有个龟兔赛跑算法😂环形链表
/**
* 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) {
if (head == null || head.next == null) {
return false;
}
// 定义快慢指针
ListNode slow = head;
ListNode fast = head.next;
while (slow != fast) {
if (fast == null || fast.next == null) {
return false;
}
slow = slow.next;
fast = fast.next.next;
}
return true;
}
}
合并两个有序链表
题目地址:21. 合并两个有序链表 - 力扣(LeetCode) (leetcode-cn.com)
思路
递归
- 判断链表是否为空,为空就返回另一个链表不做任何操作
- 否则判断两个链表哪个头节点的值更小,然后递归调用将下一个添加到结果的节点
- 递归结束条件:任以链表为空,递归结束
/**
* 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;
}
}
}
复杂度分析
-
时间复杂度:O(n + m),其中n和m分别为两个链表的长度
-
空间复杂度:O(n + m),其中n和m分别为两个链表的长度
反转字符串
题目地址:344. 反转字符串 - 力扣(LeetCode) (leetcode-cn.com)
思路:
双指针法
class Solution {
public void reverseString(char[] s) {
int len = s.length;
for (int left = 0, right = len - 1; left < right; left++, right--) {
char temp = s[left];
s[left] = s[right];
s[right] = temp;
}
}
}
复杂度分析
- 时间复杂度:O(N),其中 N为字符数组的长度。一共执行了 N/2次的交换。
- 空间复杂度:O(1)
异或法,学到了,这样更快,评论区大神多多!!!
class Solution {
public void reverseString(char[] s) {
int l = 0;
int r = s.length - 1;
while (l < r) {
//构造 a ^ b 的结果,并放在 a 中
s[l] ^= s[r];
//将 a ^ b 这一结果再 ^ b ,存入b中,此时 b = a, a = a ^ b
s[r] ^= s[l];
//a ^ b 的结果再 ^ a ,存入 a 中,此时 b = a, a = b 完成交换
s[l] ^= s[r];
l++;
r--;
}
}
}
代码均由力扣编译器,提交通过,描述编写不当地方还请大家评论区指出💪!
以上是关于刷题笔记(链表)-12的主要内容,如果未能解决你的问题,请参考以下文章
2021/6/12 刷题笔记删除链表的倒数第 N 个结点与快慢指针