3. 删除排序链表中的重复元素
题目:
给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。
示例 1:
输入: 1->1->2
输出: 1->2
思路:
用两个指针,p,q,一个在前,一个在后,q用来寻找第一个不为p的位置.
题解:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
if(head==nullptr || head->next==nullptr) return head;
else{
ListNode* p=head;
ListNode* q=p->next;
int myval=p->val;
while(q){
while(q&&(q->val==p->val )){
q=q->next;
}
p->next=q;
if(q){
p=q;
q=q->next;
}
}
return head;
}
}
};
我在笔记里总结的两种情况,一种是q在遍历后为空,一种是遍历后不为空.两种可以合在一起,
206 反转链表
题目
题解:两种方法皆可,第一种是用三个指针,p\q\t,第二种也是用三个指针,我认为第二种更流畅一些,因为把p初始化为空指针.等到q->next=p的时候也能方便的直接将头指针的next置空,就不用像第一种方法一样单独置空了.
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
// ListNode* reverseList(ListNode* head) {
// if (head==nullptr||head->next==nullptr){return head;}
// ListNode* p=head;
// ListNode* q=p->next;
// head->next=nullptr;
// while(q){
// ListNode* t=q->next;
// q->next=p;
// p=q;
// q=t;
// }
// return p;
// }
ListNode* reverseList(ListNode * head){
if (head==nullptr||head->next==nullptr){return head;}
ListNode* p=nullptr;
ListNode* q=head;
while(q){
ListNode* t=q->next;
q->next=p;
p=q;
q=t;
}
return p;
}
};
//递归方式:
ListNode* reverseList(ListNode * head){
if (head==nullptr||head->next==nullptr){return head;}
ListNode* p=reverseList(head->next);
head->next->next=head;
head->next=nullptr;
return p;
}
21 合并两链表
题目:
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。https://leetcode-cn.com/problems/merge-two-sorted-lists/
思路:
new一个指针来作为整个返回的开头
然后不断地比较两个链表l1,l2,谁小谁就加进来
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
ListNode* head=new ListNode(-1);
ListNode* p=head;
while(l1&&l2){
if (l1->val<=l2->val){
p->next=l1;
p=l1;
l1=l1->next;
}
else if (l1->val>l2->val){
p->next=l2;
p=l2;
l2=l2->next;
}
}
if (l1) p->next=l1;
if (l2) p->next=l2;
return head->next;
}
};
判断环
题目:
- 环形链表
给定一个链表,判断链表中是否有环。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
示例 1:
输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。
思路:
快慢指针,一快一慢,注意循环条件是快慢指针的指针不等(并非数值,因为可能会有重复值) 在内部再去用if语句去判断快的那个指针是不是空,是空的话就说明没有环,到头了
题解:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
bool hasCycle(ListNode *head) {
if(head==nullptr||head->next==nullptr) return false;
ListNode* slow=head->next;
ListNode* quick=head->next->next;
if (!quick||!slow) return false;
while(quick!=slow){
if(quick==nullptr ||quick->next==nullptr ) return false;
quick=quick->next->next;
slow=slow->next;
}
if (quick) return true;
else return false;//可省略
}
};
234 回文链表
题目:
请判断一个链表是否为回文链表。
示例 1:
输入: 1->2
输出: false
示例 2:
输入: 1->2->2->1
输出: true
进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/palindrome-linked-list
思路:
首先计算这个链表的长度,若为奇数,则反转前1/2,中间不要,若为偶数,也反转前1/2然后对比前面的反转链表和后面的那个链表,若相同则为回文.(此思路是我写的,但答案不是我写的,)
https://leetcode-cn.com/problems/palindrome-linked-list/solution/javashi-onkong-o1-shuang-zhi-zhen-zhao-zhong-dian-/
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isPalindrome(ListNode head) {
//如果链表为空或者链表只有一个元素,那么一定返回true
if (head == null || head.next == null) return true;
ListNode p = head, q = head, pre = null;
//循环结束后p指向(int)(n/2)号节点,n为链表长度,索引从0开始
while (q != null && q.next != null) {
q = q.next.next;//q每次向后移动两个位置
ListNode temp = p.next;//临时记录下p的后继节点
p.next = pre;//p的next指针反向
pre = p;//移动pre
p = temp;//移动p
}
if (q != null) //链表长度为奇数,此时pre指向(int)(n/2)-1号元素,p指向(int)(n/2)号元素
p = p.next;//p向后移动一位
//判断是否回文
while (p != null && pre != null) {
if (p.val != pre.val)
return false;
p = p.next;
pre = pre.next;
}
return true;
}
}