牛客网面试必刷TOP101——链表(一)

1.反转链表

牛客网面试必刷TOP101——链表(一)_第1张图片这题我使用的是直接将最前面的节点放置到最后,然后然后遍历整个链表的方法。

class Solution {
  public:
    ListNode* ReverseList(ListNode* head) {
        ListNode* newhead = nullptr;/设立一个新的头结点
        while (head) {
            ListNode* temp = head->next;/存储头结点后面的节点
            head->next = newhead;/将存储的反转链表接上去
            newhead = head;/存储最前面的节点到newhead
            head = temp;/将被夺走了头节点的链表又放回来
        }
        return newhead;
    }
};

2.链表内指定区间反转

牛客网面试必刷TOP101——链表(一)_第2张图片遍历到n的位置,然后在n到m之间执行反转链表的操作。

class Solution {
  public:
    ListNode* reverseBetween(ListNode* head, int m, int n) {
        ListNode* a = new ListNode(-1);
        a->next = head;
        ListNode* b = a;
        ListNode* c = head;
        for (int i = 1; i < m ; i++) {/遍历到n的位置
            b = c;
            c = c->next;
        }
        ListNode* e = nullptr;
        ListNode* f = nullptr;
        for (int i = m; i < n; i++) {
            f = b -> next;
            e = c -> next;
            b -> next = e;/将第一个节点后面的节点一个一个拿到前面去
            c -> next = e->next;
            e -> next = f;
        }
        return (a->next);
    }
};

3.链表中的节点每k个一组反转

牛客网面试必刷TOP101——链表(一)_第3张图片这题就开始用聪明点的方法了,反转这种操作其实应该马上想到栈,这题就是使用栈来进行操作的。

class Solution {
public:
    ListNode* reverseKGroup(ListNode* head, int k) {
        stack<int> s;
        ListNode* temp=head;
        ListNode* re=temp;
        while(head!=NULL){
        for(int i=0;i<k;i++){/每k个输出一次
            s.push(head->val);
            head=head->next;
            if(head==NULL){
                if(i<k-1) return re;
                else break;
            }
        }
        while(!s.empty()){
            temp->val=s.top();
            s.pop();
            temp=temp->next;
        }
        }
        return re;
    }
};

4.合并两个排序的链表

牛客网面试必刷TOP101——链表(一)_第4张图片这题之前在滴滴面试真题里做过,使用双指针就可以了。

class Solution {
  public:
    ListNode* Merge(ListNode* pHead1, ListNode* pHead2) {
        // write code here
        ListNode* temp = new ListNode(0);
        ListNode* out = temp;
        while (pHead1 != NULL && pHead2 != NULL) {
            if (pHead1->val <= pHead2->val) {
                temp->next = pHead1;
                pHead1 = pHead1->next;
            }
            else {
                temp->next = pHead2;
                pHead2 = pHead2->next;
            }
            temp = temp->next;
        }
        if (pHead1) temp->next = pHead1;
        if (pHead2) temp->next = pHead2;
        return out->next;
    }
};

5.合并k个已排序的链表

牛客网面试必刷TOP101——链表(一)_第5张图片这题我是将两个链表相加写成了函数,然后再调用。

#include 
class Solution {
  public:
    ListNode* add(ListNode* i, ListNode* j) {
        ListNode* tmp = new ListNode(0);
        ListNode* out = tmp;
        while (i != NULL && j != NULL) {
            if (i->val <= j->val) {
                tmp->next = i;
                i = i->next;
            } else {
                tmp->next = j;
                j = j->next;
            }
            tmp = tmp->next;
        }
        while (i) {
            tmp->next = i;
            i = i->next;
            tmp = tmp->next;
        }
        while (j) {
            tmp->next = j;
            j = j->next;
            tmp = tmp->next;
        }
        return out->next;
    }

    ListNode* mergeKLists(vector<ListNode*>& lists) {
        ListNode* cum = nullptr;
        if(lists.size()==0) return 0;
        for (int i = 0; i < lists.size(); i++) {
            cum = add(cum, lists[i]);
        }
        return cum;
    }
};

6.判断链表中是否有环

牛客网面试必刷TOP101——链表(一)_第6张图片这题使用快慢指针即可,只要它们能相等,那么就代表有环。

#include 
class Solution {
public:
    bool hasCycle(ListNode *head) {
        ListNode* fast = head;/快慢指针
        ListNode* slow = head;
        while(fast!=nullptr&&fast->next!=nullptr){
            fast=fast->next->next;
            slow=slow->next;
            if(fast==slow) return true;
        }  
        return false;
    }
};

7.链表中环的入口节点

牛客网面试必刷TOP101——链表(一)_第7张图片先快慢指针,然后将快指针变慢从头再来,就可以确定入口了。

class Solution {
public:
    ListNode* EntryNodeOfLoop(ListNode* pHead) {
        ListNode* fast = pHead;
        ListNode* slow = pHead;
        while(fast!=nullptr&&fast->next!=nullptr){
            fast=fast->next->next;
            slow=slow->next;
            if(fast==slow) break;
        }
        if(fast==nullptr||fast->next==nullptr){
            return nullptr;
        }
        else{
            fast=pHead;
            while(fast!=slow){
                fast=fast->next;
                slow=slow->next;
            }
            return fast;
        } 
    }
};

8.链表中倒数最后k个节点

牛客网面试必刷TOP101——链表(一)_第8张图片遍历过去就可以了。

class Solution {
public:
    ListNode* FindKthToTail(ListNode* pHead, int k) {
        // write code here
        int i=0;
        ListNode* tmp = pHead;
        while(pHead){
            pHead=pHead->next;
            i++;
        }
        if(k>i) return nullptr;
        for(int j=0;j<i-k;j++){
            tmp=tmp->next;
        }
        return tmp;
    }
};

谢谢观看!

你可能感兴趣的:(面试,链表,职场和发展)