2020秋招算法题笔记-链表

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;
    }
};

判断环

题目:

  1. 环形链表
    给定一个链表,判断链表中是否有环。
    为了表示给定链表中的环,我们使用整数 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;
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值