LeetCode刷题日记day4

leetcode面试题02.07.链表相交

 思路:哈希表解法,通过建立集合类型的哈希表,先将链表A的结点都储存进集合中,在遍历链表B依次对比,若在哈希表中出现则此结点为相交结点。

#include <iostream>
#include <unordered_set>

using namespace std;

struct ListNode {
    int val;
    ListNode *next;

    ListNode(int x) : val(x), next(NULL) {}
};

class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        unordered_set<ListNode *> visited;  //结点集合哈希表
        ListNode *temp = headA;
        while (temp != nullptr) {
            visited.insert(temp);
            temp = temp->next;
        }
        temp = headB;
        while (temp != nullptr) {
            if (visited.count(temp)) {
                return temp;
            }
            temp = temp->next;
        }
        return nullptr;
    }
};

LeetCode19删除链表的倒数第n个结点

 思路:

  • 双指针
  1.  双指针法:头一遍遍历整个链表统计出链表的长度end,第二遍用新结点p记录head的信息初始化val0first从头开始直到end-n停止然后另结点temp->next = temp->next->next,之后返回链表头结点。
  2. 栈:简单明了就是将每个元素都入栈,然后每出栈一个n就减一,直到n等于0,然后另temp->next = temp -> next ->next.
#include <iostream>
#include <stack>

using namespace std;

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 *removeNthFromEnd(ListNode *head, int n) {
        int first = 1, end = 1;
        ListNode *temp = head;
        while (temp != nullptr) {
            temp = temp->next;
            end++;
        }
        int i = end - n;
        ListNode *p = new ListNode(0, head);    //新建一个结点结构存储head的地址信息val初始化为0
        temp = p;
        while (temp != nullptr) {
            if (first == i) {
                temp->next = temp->next->next;
                break;
            }
            temp = temp->next;
            first++;
        }
        ListNode *ans = p -> next;
        delete p;
        return ans;
    }
};

//栈
class Solutions {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode* dummy = new ListNode(0, head);
        stack<ListNode*> stk;
        ListNode* cur = dummy;
        while (cur) {
            stk.push(cur);
            cur = cur->next;
        }
        for (int i = 0; i < n; ++i) {
            stk.pop();
        }
        ListNode* prev = stk.top();
        prev->next = prev->next->next;
        ListNode* ans = dummy->next;
        delete dummy;
        return ans;
    }
};

LeetCode24两两交换表中结点

思路:迭代法,储存三个结点的信息,将要交换的两个结点,以及前一个结点。设分别为p1,p2,p3,那么就需要将p2->next = p3 -> next,p3->next = p2,p1->next = p3 。

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 *swapPairs(ListNode *head) {
        if (head == nullptr) {
            return head;
        }
        ListNode *dummyHead = new ListNode(0);
        dummyHead->next = head;
        ListNode *temp = dummyHead;
        while (temp->next != nullptr && temp->next->next != nullptr) {
            //记录三个结点分别是两个需要交换的结点和其前一个结点
            ListNode *node1 = temp->next;
            ListNode *node2 = temp->next->next;
            temp->next = node2;
            node1->next = node2->next;
            node2->next = node1;
            temp = node1;
        }
        return dummyHead->next;
    }
};

 LeetCode142环形链表

思路:哈希表,同样是建立一个集合哈希表,记录遍历过程中的每一个结点,当遍历到相同的结点set.count(temp) = true,就返回当前结点。

#include <iostream>
#include <unordered_set>
using namespace std;

struct ListNode {
    int val;
    ListNode *next;

    ListNode(int x) : val(x), next(NULL) {}
};

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        unordered_set<ListNode*> s;
        ListNode *temp = head;
        while(temp != nullptr) {
            if(s.count(temp)) {
                return temp;
            }
            s.insert(temp);
            temp = temp -> next;
        }
        return nullptr;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值