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

1.删除链表的倒数第n个节点

牛客网面试必刷TOP101——链表(二)_第1张图片这题我采用的是先遍历得到总长度,然后根据总长度来进行遍历到倒数第n个节点。

class Solution {
  public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        int i = 0;
        ListNode* tmp = new ListNode(-1);
        tmp->next = head;
        ListNode* mid = tmp;
        while (head->next) {
            head = head->next;
            i++;
        }
        for (int j = 0; j < i - n + 1; j++) {
            tmp = tmp->next;
        }
        tmp->next = tmp->next->next;
        return mid->next;
    }
};

2.两个链表的第一个公共节点

牛客网面试必刷TOP101——链表(二)_第2张图片这题开始我就开始使用一个很有意思的容器了,set容器,它有一个特性,不允许元素重复,所以只要将一个压入set,再尝试压另一个,它就会出现count为1,即为第一个公共结点。

class Solution {
public:
    ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
        set<ListNode*> s;
		while(pHead1){
			s.insert(pHead1);
			pHead1=pHead1->next;
		}
		while(pHead2){
			if(s.count(pHead2)==true){
				break;
			}
			pHead2=pHead2->next;
		}
		return pHead2;
    }
};

3.链表相加

牛客网面试必刷TOP101——链表(二)_第3张图片这道题目花了我比较久的时间,我采用的是使用三个栈的方式,将要相加的链表压入两个栈,然后结果压入第三个栈。

#include 
class Solution {
public:
    ListNode* addInList(ListNode* head1, ListNode* head2) {
        // write code here
        stack<int> s1;
        stack<int> s2;
        stack<int> s3;
        ListNode* head3 = new ListNode(0);
        ListNode* ac = head3;
        int tmp=0;
        while(head1){
            s1.push(head1->val);
            head1=head1->next;       
            }
        while(head2){
            s2.push(head2->val); 
            head2=head2->next;      
            }
        while(!s1.empty()&&!s2.empty()){
            s3.push((s1.top()+s2.top()+tmp)%10);
            tmp=(s1.top()+s2.top()+tmp)/10;
            s1.pop();
            s2.pop();
        }
        while(!s1.empty()) {
            s3.push((s1.top()+tmp)%10);
            tmp=(s1.top()+tmp)/10;
            s1.pop();
        } 
        while(!s2.empty()) {
            s3.push((s2.top()+tmp)%10);
            tmp=(s2.top()+tmp)/10;
            s2.pop();
        }
        s3.push(tmp);
        if(s3.top()==0) s3.pop();
        while(!s3.empty()){
            ListNode* node = new ListNode(1);
            head3->next = node;
            node->val=s3.top();
            s3.pop();
            head3 = head3->next;
        }
        return ac->next;
    }
};

4.单链表的排序

牛客网面试必刷TOP101——链表(二)_第4张图片这题偷了一下懒,使用了C++自带的sort函数,但是sort之后要记得再反转一下链表。

class Solution {
  public:
    ListNode* sortInList(ListNode* head) {
        vector<int>tmp;
        int i = 0;
        while (head) {
            tmp.push_back(head->val);
            head = head->next;
            i++;
        }
        sort(tmp.begin(), tmp.end());
        ListNode* out = new ListNode(0);
        ListNode* t = out;
        for (int j = 0; j < i; j++) {
            ListNode* node = new ListNode(0);
            node->val = tmp.back();
            tmp.pop_back();
            out->next = node;
            out = out->next;
        }
        ListNode* newhead = nullptr;
        while (t->next) {
            ListNode* temp = t->next->next;
            t->next->next = newhead;
            newhead = t->next;
            t->next = temp;
        }
        return newhead;
    }
};

5.判断一个链表是否为回文结构

牛客网面试必刷TOP101——链表(二)_第5张图片很粗暴,压进数组,直接遍历一半,和后面一半对比即可。

class Solution {
public:
    bool isPail(ListNode* head) {
        int tmp[100000],i=0;
        while(head){
            tmp[i]=head->val;
            head=head->next;
            i++;
        }
        if(i==1) return true;
        for(int j=0;j<=i/2;j++){
            if(tmp[j]!=tmp[i-j-1]){
                return  false;
            }
        }
        return true;
    }
};

6.链表的奇偶重排

牛客网面试必刷TOP101——链表(二)_第6张图片奇数节点压进一个队列,偶数节点压进一个队列,然后在压出就可以了。

class Solution {
  public:
    ListNode* oddEvenList(ListNode* head) {
        queue<int> q1;
        queue<int> q2;
        int tmp = 1;
        while (head) {
            if (tmp % 2 == 0) {
                q2.push(head->val);
            } else {
                q1.push(head->val);
            }
            tmp++;
            head = head->next;
        }
        ListNode* sum = new ListNode(0);
        ListNode* out = sum;
        while (!q1.empty()) {
            ListNode* node = new ListNode(0);
            node->val = q1.front();
            q1.pop();
            sum->next = node;
            sum = node;
        }
        while (!q2.empty()) {
            ListNode* node = new ListNode(0);
            node->val = q2.front();
            q2.pop();
            sum->next = node;
            sum = node;
        }
        return out->next;
    }
};

7.删除有序链表中重复的元素-1

牛客网面试必刷TOP101——链表(二)_第7张图片简简单单一个set,就是这个set的遍历一般可能有点陌生。

#include
class Solution {
public:
    ListNode* deleteDuplicates(ListNode* head) {
        // write code here
        set<int> s;
        while(head){
                s.insert(head->val);
                head = head->next;
        }
        ListNode* out = new ListNode(0);
        ListNode* ac = out;
        for(auto item:s){
            ListNode* temp = new ListNode(item);
            out->next = temp;
            out = temp;
        }
        return ac->next;
    }
};

8.删除有序链表中重复的元素-2

牛客网面试必刷TOP101——链表(二)_第8张图片这题用set和vector,有重复就用vector记录下来,最后用erase一起删,就可以保证删除干净了。

class Solution {
  public:
    #include
    #include
    ListNode* deleteDuplicates(ListNode* head) {
        set<int> s;
        vector<int> v;
        while(head){
            if(s.count(head->val)==1){
                v.push_back(head->val);
            }
            s.insert(head->val);
            head = head->next;
        }
        while(!v.empty()){
            s.erase(v.back());
            v.pop_back();
        }
        ListNode* out = new ListNode(0);
        ListNode* ac = out;
        for(auto item:s){
            ListNode* temp = new ListNode(item);
            out->next = temp;
            out = temp;
        }
        return ac->next;
    }
};

谢谢阅读!

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