1. leetcode(数组 + 链表)

1. leetcode 739 每日温度

// 使用单调栈
class Solution {
    
    
public:
    vector<int> dailyTemperatures(vector<int>& temperatures) {
    
    
        int n = temperatures.size();
        vector<int> res(n, 0);
        stack<int> st;    // 栈中存储数组的下标
        for (int i = 0; i < temperatures.size(); ++i) {
    
    
            while (!st.empty() && temperatures[i] > temperatures[st.top()]) {
    
    
                auto t = st.top(); st.pop();
                res[t] = i - t;
            }
            st.push(i);
        }
        return res;
    }
};

2. leetcode 316 去除重复字母

//单调栈

class Solution {
    
    
public:
    string removeDuplicateLetters(string s) {
    
    
        string res;
        unordered_map<char, int> hash, h;
        for( int i = 0; i < s.size(); i++ )
            hash[s[i]]++;
        stack<char> stk;
        for( int i = 0; i < s.size(); i++ )
        {
    
    
            // 如果该字符在栈中出现过,那么跳过即可
            // 同时需要对hash表操作一下
            if(stk.size() && h[s[i]] ) 
            {
    
    
                hash[s[i]]--;
                continue;
            }
            // 单调栈
            // 如果读入的字符比栈顶的字符小,并且在字符串的后面还有同样的字符,那么栈顶可以一直弹出
            // 直到栈顶字符字典序比s[i]小或i后面没有同样的字符为止
            // h记得减一下
            while( stk.size() && stk.top() > s[i] && hash[stk.top()])
            {
    
    
                h[stk.top()]--;
                 stk.pop();
            }
            
            stk.push(s[i]);
            h[s[i]]++;
            hash[s[i]]--;
        }
        // 出栈 + 逆序
        while( stk.size())
        {
    
    
            res += stk.top();
            stk.pop();
        }
        reverse(res.begin(), res.end());
        return res;
    }
};

3. leetcode 402 移除K位元素

class Solution {
    
    
public:
    string removeKdigits(string num, int k) {
    
    
        int n = num.size();
        stack<char> s; //单调递减栈 栈顶元素最大
        string ans;
        for(int i = 0; i < n; i++){
    
    
            while(!s.empty() && num[i] < s.top() && k){
    
     //删除k个元素
                s.pop();
                k--;
            }
            s.push(num[i]);
        }
        while(k){
    
      //前面删除了m个元素,m<k时,删除末尾的k-m个元素
            s.pop();
            k--;
        }
        while(!s.empty()){
    
    
            ans += s.top();
            s.pop();
        }
        if(ans=="") return "0";
        reverse(ans.begin(), ans.end());
        int cnt = 0;
        while(cnt < ans.size() && ans[cnt] == '0'){
    
    
            cnt++;  //结果值中可能有前导0
        }
        return cnt == ans.size() ? "0" : ans.substr(cnt, ans.size() - cnt); //可能为全0
    }
};

4. leetcode 59 螺旋矩阵

// 模拟法
class Solution {
    
    
public:
    vector<vector<int>> generateMatrix(int n) {
    
    
        int num = 1;
        int left = 0, right = n - 1, top = 0, bottom = n - 1;

        vector<vector<int>> res(n, vector<int>(n, 0));
        while (num <= n*n) {
    
    
            for (int i = left;  i <= right; i++) {
    
    
                res[top][i] = num++;
            }
            ++top;
            for(int i = top; i <= bottom; i++) {
    
    
                res[i][right] = num++;
            }
            --right;
            for (int i = right; i >= left; --i) {
    
    
                res[bottom][i] = num++;
            }
            --bottom;
            for (int i = bottom; i >= top; --i) {
    
    
                res[i][left] = num++;
            }
            ++left;
        }
        return res;
    }
};

5. leetcode 54 螺旋矩阵

// 这里的方法不需要记录已经走过的路径,所以执行用时和内存消耗都相对较小

//     1首先设定上下左右边界
//     2其次向右移动到最右,此时第一行因为已经使用过了,可以将其从图中删去,体现在代码中就是重新定义上边界
//     3判断若重新定义后,上下边界交错,表明螺旋矩阵遍历结束,跳出循环,返回答案
//     4若上下边界不交错,则遍历还未结束,接着向下向左向上移动,操作过程与第一,二步同理
//     5不断循环以上步骤,直到某两条边界交错,跳出循环,返回答案

class Solution {
    
    
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
    
    
        vector<int> res;
        if (matrix.empty()) return res;   //若数组为空,则直接返回答案
        //赋值上下左右边界
        int left = 0, right = matrix[0].size() - 1, top = 0, bottom = matrix.size() - 1;

        while (true) {
    
    
            for (int i = left; i <= right; ++i) {
    
    
                res.push_back(matrix[top][i]);
            }
            // 重新设定上边界,若上边界大于下边界,则遍历完成
            if (++top > bottom) break; 
            for (int i = top; i <= bottom; ++i) {
    
    
                res.push_back(matrix[i][right]);
            }
            if (--right < left) break;
            for (int i = right; i >= left; --i) {
    
    
                res.push_back(matrix[bottom][i]);
            }
            if (--bottom < top) break;
            for (int i = bottom; i >= top; --i) {
    
    
                res.push_back(matrix[i][left]);
            }
            if (++left > right) break;
        }
        return res;
    
    }
};

6. leetcode 203 移除链表元素


/**
 * 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* removeElements(ListNode* head, int val) {
    
    
        ListNode* dummyhead = new ListNode();
        dummyhead->next = head;

        ListNode* cur = dummyhead;
        while (cur->next != NULL) {
    
    
            if (cur->next->val == val) {
    
    
                ListNode* tmp = cur->next;
                cur->next = cur->next->next;
                delete tmp;
            } else {
    
    
                cur = cur->next;
            }
        }
        // ListNode* node = dummyhead->head;
        // delete dummyhead;
        return dummyhead->next;
    }
};

//递归  
//链表的定义具有递归性质

class Solution {
    
    
public:
    ListNode* removeElements(ListNode* head, int val) {
    
    
        if (head == nullptr) {
    
    
            return head;
        }
        head->next = removeElements(head->next, val);
        return head->val == val ? head->next : head;
    }
};

7. leetcode 707 设计链表


class MyLinkedList {
    
    

public:
    struct ListNode {
    
    
        int val;
        ListNode* next;
        ListNode(int val) : val(val), next(nullptr) {
    
    }
    };

    MyLinkedList() {
    
    
        ListNode* dummyhead = new ListNode(0);
        int size = 0;
    }
    
    int get(int index) {
    
    
        if (index < 0 || index > (size -1)) {
    
    
            return -1;
        }
        ListNode* cur = dummyhead->next;
        while (index--) {
    
    
            cur = cur->next;
        }
        return cur->val;
    }
    
    void addAtHead(int val) {
    
    
        ListNode* newNode = new ListNode(val);
        newNode->next = dummyhead->next;
        dummyhead->next = newNode;
        size++;
    }
    
    void addAtTail(int val) {
    
    
        ListNode* newNode = new ListNode(val);
        ListNode* cur = dummyhead;
        while (cur->next != NULL) {
    
    
            cur = cur->next;
        }
        cur->next = newNode;
        size++;
    }
    
    void addAtIndex(int index, int val) {
    
    
        if (idx > index) {
    
    
            return;
        }
        ListNode* newNode = ListNode(val);
        ListNode* cur = dummyhead;

        while (index--) {
    
    
            cur = cur->next;
        }
        newNode->next = cur->next;
        cur->next = newNode;
        size++;
    }
    
    void deleteAtIndex(int index) {
    
    
        if (index >= size || index < 0) {
    
    
            return;
        }
        ListNode* cur = dummyhead;
        while (index--) {
    
    
            cur = cur->next;
        }
        ListNode* tmp = cur->next;
        cur->next = cur->next->next;
        delete tmp;
        size--;
    }
};

/**
 * Your MyLinkedList object will be instantiated and called as such:
 * MyLinkedList* obj = new MyLinkedList();
 * int param_1 = obj->get(index);
 * obj->addAtHead(val);
 * obj->addAtTail(val);
 * obj->addAtIndex(index,val);
 * obj->deleteAtIndex(index);
 */


#include <iostream>
using namespace std;

//C++单向链表模板
class MyListForward
{
    
    
private:
    struct ListNode
    {
    
    
        int val;
        ListNode *next;
        ListNode(int x):val(x),next(nullptr){
    
    }
    };
    ListNode* head;
public:
    MyListForward():head(nullptr){
    
    }

    //获得链表中第index个节点的值
    int get(int index){
    
    
        int i=0;
        ListNode *p=head;
        while(p&&i<index){
    
    
            p=p->next;
            i++;
        }
        if(p)return p->val;
        else return -1;
    }

    //在链表头部插一个值为val的节点
    void addAtHead(int val){
    
    
        ListNode *p=new ListNode(val);
        p->next=head;
        head=p;//更换头节点
    }

    //在链表尾部添加一个值为val的节点
    void addAtTail(int val){
    
    
        ListNode *p=new ListNode(val);
        //链表为空,直接将新节点作为头节点
        if(head==nullptr){
    
    
            head=p;
            return;
        }
        ListNode *q=head;
        //遍历直到q的next节点为空
        while(q->next){
    
    
            q=q->next;
        }
        q->next=p;
    }

    //在索引为index的节点之前添加值为val的节点
    void addAtIndex(int index,int val){
    
    
        ListNode *node=new ListNode(val);
        //1、index小于等于0,直接在头部插入节点
        if(index<=0)
        {
    
    //若index小于等于0,我们仅需要在头节点前面插入新节点就行了
        //注意这里不能使用指针p,因为p=node时,p所指向的地址发生了变化,head指向的地址没有变化,所以我们这里要使用指针head
            node->next=head;
            head=node;
            return;
        }
        int i=0;
        ListNode *p=head;
        //在索引为index的节点之前插入新节点,我们需要找到它的前驱节点,然后插入在它的前驱节点后面
        while(p&&i<index-1)
        {
    
    
            p=p->next;
            ++i;
        }
        //2、p为索引节点的前驱节点
        if(p)
        {
    
    
            node->next=p->next;
            p->next=node;
        }
    }

    //删除索引为index的节点
    void deleteAtIndex(int index){
    
    
        //1、index为0,我们直接删除head节点
        if(index==0&&head!=nullptr)
        {
    
    
            ListNode *del=head;
            head=head->next;
            delete del;
            return;
        }
        int i=0;
        ListNode* p=head;
        //删除索引为index的节点,我们需要找到它的前驱节点p,p->next为需要删除节点
        while(p&&i<index-1)
        {
    
    
            p=p->next;
            i++;
        }
        //2、index超过链表范围,删除失败
        if(!p)return;
        //3、index的位置合法,我们找到需要删除的p->next节点
        if(p->next)
        {
    
    
            ListNode *del=p->next;
            p->next=del->next;
            delete del;
        }
    }

    int length(){
    
    
        int i=0;
        ListNode *p=head;
        while(p){
    
    
            i++;
            p=p->next;
        }
        return i;
    }
};

int main()
{
    
    
    MyListForward mlf;
    mlf.addAtIndex(0,10);
    mlf.addAtIndex(0,20);
    mlf.addAtIndex(1,30);
    for(int i=0;i<mlf.length();++i){
    
    
        cout<<mlf.get(i)<<" ";
    }
    cout<<endl;
    system("pause");
}


#include <iostream>
using namespace std;

//C++双向链表模板
class MyList
{
    
    
private:
    struct ListNode
    {
    
    
        int val;
        ListNode *next,*prev;
        ListNode(int x):val(x),next(nullptr),prev(nullptr){
    
    }
    };
private:
    //头节点尾节点都为空,表示为空链表
    ListNode *head,*tail;
    int size=0;
public:
    MyList():size(0),head(nullptr),tail(nullptr){
    
    }

    int get(int index){
    
    
        int i=0;
        ListNode *p=head;
        while(p&&i<index){
    
    
            p=p->next;
            i++;
        }
        if(p)return p->val;
        else return -1;
    }

    void addAtHead(int val){
    
    
        if(head!=nullptr){
    
    
            ListNode *node=new ListNode(val);
            node->next=head;
            head->prev=node;
            head=node;
        }
        else{
    
    
            head=new ListNode(val);
            tail=head;
        }
        ++size;
    }

    void addAtTail(int val){
    
    
        if(tail!=nullptr){
    
    
            ListNode *node=new ListNode(val);
            node->prev=tail;
            tail->next=node;
            tail=node;
        }
        else{
    
    //尾节点为空,那么头节点也为空,然后首尾节点都为新节点
            tail=new ListNode(val);
            head=tail;
        }
        ++size;
    }

    void addAtIndex(int index,int val){
    
    
        //首先排除三种特殊情况的index,然后剩下来的index肯定在链表内
        if(index<=0){
    
    
            addAtHead(val);
            return;
        }
        if(index==size){
    
    
            addAtTail(val);
            return;
        }
        if(index>size)return;
        ListNode *p=nullptr,*cur=head;
        int i=0;
        while(cur&&i<index){
    
    
            p=cur;
            cur=cur->next;
            i++;
        }
        ListNode *node=new ListNode(val);
        //由于前面已经将特殊情况的index排除了,现在的p和cur都有效,都在链表内
        p->next=node;
        node->prev=p;
        node->next=cur;
        cur->prev=node;
        size++;
    }

    void deleteAtIndex(int index){
    
    
        //链表为空时,不能删除
        if(!head)return;
        if(index==0)
        {
    
    
            ListNode *del=head;
            head=head->next;
            if(head){
    
    //链表有2个以上节点
                head->prev=nullptr;
            }
            else{
    
    //链表只有一个节点,将尾部制空
                tail=nullptr;
            }
            delete del;
            size--;
            return;
        }
        //index为最后为尾节点,我们需要删除尾节点
        if(index==size-1){
    
    
            ListNode *del=tail;
            tail=tail->prev;
            //注意这里不用处理tail为空,因为tail为空的话,那么链表只有单个节点
            //然而单个节点只能删除0号节点,只有index为0时才能删除,前面已经处理过了index为0的情况了,所以这里不在处理
            if(tail){
    
    
                tail->next=nullptr;
            }
            delete del;
            size--;
            return;
        }
        int i=0;
        ListNode *p=nullptr,*cur=head;
        while(cur){
    
    
            if(i==index){
    
    
                ListNode *del=cur;
                p->next=cur->next;
                if(cur->next){
    
    
                    cur->next->prev=p;
                }
                delete del;
                size--;
                return;
            }
            p=cur;
            cur=cur->next;
            ++i;
        }
    }

    int length(){
    
    
        return size;
    }
};

int main()
{
    
    
    MyList ml;
    ml.addAtHead(1);
    ml.addAtTail(3);
    ml.addAtHead(4);
    ml.addAtHead(5);
    ml.addAtIndex(1,2);
    for(int i=0;i<ml.length();++i){
    
    
        cout<<ml.get(i)<<" ";
    }
    cout<<endl;
    ml.deleteAtIndex(1);
    for(int i=0;i<ml.length();++i){
    
    
        cout<<ml.get(i)<<" ";
    }
    cout<<endl;
    system("pause");
}

8. leetcode 206 反转链表

// 迭代


/**
 * 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* reverseList(ListNode* head) {
    
    
        ListNode* tmp;
        ListNode* cur = head;
        ListNode* pre = NULL;

        while (cur) {
    
    
            tmp = cur->next;   // 保存cur的下一个节点
            cur->next = pre;

            pre = cur;
            cur = tmp;
        }
        return pre;
    }
};



//递归
/**
 * 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* reverseList(ListNode* head) {
    
    
        ListNode* tmp;
        ListNode* cur = head;
        ListNode* pre = NULL;

        while (cur) {
    
    
            tmp = cur->next;
            cur->next = pre;

            pre = cur;
            cur = tmp;
        }
        return pre;
    }
};

9. leetcode 24 两两交换链表节点

/**
 * 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* swapPairs(ListNode* head) {
    
    
        ListNode* dummyhead = new ListNode(0);
        dummyhead->next = head;   //虚拟头节点指向head,方便后边进行删除操作;
        ListNode* cur = dummyhead;
        while (cur->next != nullptr && cur->next->next != nullptr) {
    
    
            ListNode* tmp = cur->next;
            ListNode* tmp1 = cur->next->next->next;
            
            cur->next = cur->next->next;
            cur->next->next = tmp;
            cur->next->next->next = tmp1;

            cur->next->next;  // 移动两位,进行下一轮交换
        }
        return dummyhead->next;
    }
};

//递归
//递归终止条件是 链表中没有节点,或者链表中只有一个节点
class Solution {
    
    
public:
    ListNode* swapPairs(ListNode* head) {
    
    
        if (head == nullptr || head->next == nullptr) {
    
    
            return head;
        }
        ListNode* newhead = head->next;
        head->next = swapPairs(newhead->next);
        newhead->next = head;
        return newhead;
    }
};

//迭代
class Solution {
    
    
public:
    ListNode* swapPairs(ListNode* head) {
    
    
        ListNode* dummyhead = new ListNode(0);
        dummyhead->next = head;
        ListNode* cur = dummyhead;
        while (cur->next != nullptr && cur->next->next != nullptr) {
    
    
            ListNode* tmp = cur->next;
            ListNode* tmp1 = cur->next->next;

            cur->next = tmp1;
            tmp->next = tmp1->next;
            tmp1->next = tmp;
            cur = tmp;
        }
        return dummyhead->next;
    }
};

10. leetcode 19 删除链表倒数第N个节点

/**
 * 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* removeNthFromEnd(ListNode* head, int n) {
    
    
        ListNode* dummyhead = new ListNode(0);
        dummyhead->next = head;

        ListNode* slow = dummyhead;
        ListNode* fast = dummyhead;
        while (n-- && fast != nullptr) {
    
    
            fast = fast->next;
        }
        fast = fast->next;
        while (fast != nullptr) {
    
    
            fast  = fast->next;
            slow  = slow->next;
        }
        slow->next = slow->next->next;
        return dummyhead->next;
    }
};

//计算链表的长度
class Solution {
    
    
public:
    int getLength(ListNode* head) {
    
    
        int length = 0;
        while (head) {
    
    
            ++length;
            head = head->next;
        }
        return length;
    }

    ListNode* removeNthFromEnd(ListNode* head, int n) {
    
    
        ListNode* dummyhead = new ListNode(0);
        dummyhead->next = head;
        int length = getLength(head);
        ListNode* cur = dummyhead;
        for (int i = 1; i < length - n + 1; ++i) {
    
    
            cur = cur->next;
        }
        cur->next = cur->next->next;
        ListNode* res = dummyhead->next;
        delete dummyhead;
        return res;

    }
};
//栈
class Solution {
    
    
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
    
    
        ListNode* dummyhead = new ListNode(0, head);
        stack<ListNode*> st;
        ListNode* cur = dummyhead;
        while (cur) {
    
    
            st.push(cur);
            cur = cur->next;
        }
        for (int i = 0; i < n; ++i) {
    
    
            st.pop();
        }
        ListNode* pre = st.top();
        pre->next = pre->next->next;
        ListNode* res = dummyhead->next;
        delete dummyhead;
        return res;
    }
};

11. 面试题 02.07. 链表相交

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
 //双指针
class Solution {
    
    
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
    
    
        ListNode* A = headA, * B = headB;
        while (A != B) {
    
    
            A = A != nullptr ? A->next : headB;
            B = B != nullptr ? B->next : headA;
        }
        return A;
    }
};

12. leetcode 142 环形链表II

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
    
    
public:
    ListNode *detectCycle(ListNode *head) {
    
    
        ListNode* fast = head;
        ListNode* slow = head;
        while (fast != NULL && fast->next != NULL) {
    
    
            slow = slow->next;
            fast = fast->next->next;
            if (slow == fast) {
    
    
                ListNode* index1 = fast;
                ListNode* index2 = head;
                while (index1 != index2) {
    
    
                    index1 = index1->next;
                    index2 = index2->next;
                }
                return index2;

            }
        }

        return NULL;
    }
};

//哈系表
class Solution {
    
    
public:
    ListNode *detectCycle(ListNode *head) {
    
    
        unordered_set<ListNode *> visited;
        while (head != nullptr) {
    
    
            if (visited.count(head)) {
    
    
                return head;
            }
            visited.insert(head);
            head = head->next;
        }
        return nullptr;
    }
};


//快慢指针
class Solution {
    
    
public:
    ListNode *detectCycle(ListNode *head) {
    
    
        ListNode *slow = head, *fast = head;
        while (fast != nullptr) {
    
    
            slow = slow->next;
            if (fast->next == nullptr) {
    
    
                return nullptr;
            }
            fast = fast->next->next;
            if (fast == slow) {
    
    
                ListNode *ptr = head;
                while (ptr != slow) {
    
    
                    ptr = ptr->next;
                    slow = slow->next;
                }
                return ptr;
            }
        }
        return nullptr;
    }
};

猜你喜欢

转载自blog.csdn.net/weixin_44847326/article/details/123487347