数据结构总结

1.链表

1.1 移除链表元素

203. 移除链表元素 - 力扣(LeetCode)

代码实现(C++/Java)

cpp 复制代码
/**
 * 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 * dummy=new ListNode(0);//虚拟头节点
        dummy->next=head;
        ListNode* cur=dummy;
        while(cur->next!=nullptr){
            if(cur->next->val==val){
                cur->next=cur->next->next;
            }else {
                cur=cur->next;
            }
        }
        return dummy->next;
    }
};
java 复制代码
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode removeElements(ListNode head, int val) {
        ListNode dummy=new ListNode(0);
        dummy.next=head;
        ListNode cur=dummy;
        while(cur.next!=null){
            if(cur.next.val==val){
                cur.next=cur.next.next;
            }else {
                cur=cur.next;
            }
        }
        return dummy.next;
    }
}

1.2 设计链表

707. 设计链表 - 力扣(LeetCode)

代码实现(C++/Java)

cpp 复制代码
class MyLinkedList {
public:
   struct LinkNode {
        int val;
        LinkNode* next;
        LinkNode(int val) : val(val), next(nullptr) {}
    };
    LinkNode* dummy; //虚拟头节点
    int size; //链表元素数量
    //构造函数
    MyLinkedList() {
        dummy=new LinkNode(0);
        size=0;
    }
    
    int get(int index) {
        if(index<0 || index>=size) return -1;
        LinkNode* cur=dummy->next;
        while(index--) cur=cur->next;
        return cur->val;
    }

    //头插
    void addAtHead(int val) {
        LinkNode* newNode=new LinkNode(val);
        newNode->next=dummy->next;
        dummy->next=newNode;
        size++;
    }
    
    //尾插
    void addAtTail(int val) {
        LinkNode* newNode=new LinkNode(val);
        LinkNode* cur=dummy;
        while(cur->next!=nullptr){
            cur=cur->next;
        }
        cur->next=newNode;
        size++;
    }
    
    void addAtIndex(int index, int val) {
        if(index<0 || index>size) return;
        LinkNode* newNode=new LinkNode(val);
        LinkNode* cur=dummy;
        while(index--){
            cur=cur->next;
        }
        newNode->next=cur->next;
        cur->next=newNode;
        size++;
    }
    
    void deleteAtIndex(int index) {
        if(index<0 || index>=size) return;
        LinkNode* cur=dummy;
        while(index--) cur=cur->next;
        cur->next=cur->next->next;
        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);
 */
java 复制代码
class MyLinkedList {
    //定义链表节点类
    private class LinkedNode{
        int val;
        LinkedNode next;
        LinkedNode(int val){
            this.val=val;
            this.next=null;
        }
    }
    private LinkedNode dummyHead; //虚拟头节点
    private int size;

    public MyLinkedList() {
        dummyHead=new LinkedNode(0);
        size=0;
    }
    
    public int get(int index) {
        if(index<0 || index>=size) return -1;
        LinkedNode cur=dummyHead.next;
        while(index--!=0) cur=cur.next;
        return cur.val;
    }
    
    public void addAtHead(int val) {
        LinkedNode newNode=new LinkedNode(val);
        newNode.next=dummyHead.next;
        dummyHead.next=newNode;
        size++;
    }
    
    public void addAtTail(int val) {
        LinkedNode newNode=new LinkedNode(val);
        LinkedNode cur=dummyHead;
        while(cur.next!=null) cur=cur.next;
        cur.next=newNode;
        size++;
    }
    
    public void addAtIndex(int index, int val) {
        if(index<0 || index>size) return;
        LinkedNode newNode=new LinkedNode(val);
        LinkedNode cur=dummyHead;
        while(index--!=0) cur=cur.next;
        newNode.next=cur.next;
        cur.next=newNode;
        size++;
    }
    
    public void deleteAtIndex(int index) {
        if(index<0 || index>=size) return;
        LinkedNode cur=dummyHead;
        while(index--!=0) cur=cur.next;
        cur.next=cur.next.next;
        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);
 */

1.3 反转链表

206. 反转链表 - 力扣(LeetCode)

代码实现(C++/Java)

cpp 复制代码
/**
 * 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* prev=nullptr;
        ListNode* cur=head;
        while(cur!=nullptr){
            ListNode* next=cur->next;
            cur->next=prev;
            prev=cur;
            cur=next;
        }
        return prev;
    }
};
java 复制代码
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode prev=null;
        ListNode cur=head;
        while(cur!=null){
            ListNode next=cur.next;
            cur.next=prev;
            prev=cur;
            cur=next;
        }
        return prev;


    }
}

1.4 两两交换链表中的节点

24. 两两交换链表中的节点 - 力扣(LeetCode)

代码实现(C++/Java)

cpp 复制代码
/**
 * 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* dummy=new ListNode(0);
        dummy->next=head;
        ListNode* cur=dummy;
        while(cur->next!=nullptr && cur->next->next!=nullptr){
            ListNode* t1=cur->next;
            ListNode* t2=cur->next->next->next;
            cur->next=cur->next->next;
            cur->next->next=t1;
            cur->next->next->next=t2;
            cur=cur->next->next;
        }
        return dummy->next;
    }
};
java 复制代码
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode swapPairs(ListNode head) {
        ListNode dummy=new ListNode(0);
        dummy.next=head;
        ListNode cur=dummy;
        while(cur.next!=null && cur.next.next!=null){
            ListNode t1=cur.next;
            ListNode t2=cur.next.next.next;
            cur.next=cur.next.next;
            cur.next.next=t1;
            cur.next.next.next=t2;
            cur=cur.next.next;
        }
        return dummy.next;
    }
}

1.5 删除链表的倒数第N个节点

19. 删除链表的倒数第 N 个结点 - 力扣(LeetCode)

代码实现(C++/Java)

cpp 复制代码
/**
 * 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* dummy=new ListNode(0);
        dummy->next=head;
        ListNode* slow=dummy;
        ListNode* fast=dummy;
        for(int i=1;i<=n+1;i++) fast=fast->next;

        while(fast!=nullptr){
            slow=slow->next;
            fast=fast->next;
        }
        slow->next=slow->next->next;
        return dummy->next;
    }
};
java 复制代码
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummy=new ListNode(0);
        dummy.next=head;
        ListNode fast=dummy;
        ListNode slow=dummy;
        for(int i=1;i<=n+1;i++) fast=fast.next;
        while(fast!=null){
            slow=slow.next;
            fast=fast.next;
        }
        slow.next=slow.next.next;
        return dummy.next;
    }
}

1.6 链表相交

面试题 02.07. 链表相交 - 力扣(LeetCode)

代码实现(C++/Java)

cpp 复制代码
/**
 * 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* pa=headA;
        ListNode* pb=headB;
        while(pa!=pb){
            if(pa!=nullptr) pa=pa->next;
            else pa=headB;
            if(pb!=nullptr) pb=pb->next;
            else pb=headA;
        }
        return pa;
    }
};
java 复制代码
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        ListNode pa=headA;
        ListNode pb=headB;
        while(pa!=pb){
            if(pa!=null) pa=pa.next;
            else pa=headB;
            if(pb!=null) pb=pb.next;
            else pb=headA;
        }
        return pa;
    }
}

1.7 环形链表

142. 环形链表 II - 力扣(LeetCode)

代码实现(C++/Java)

cpp 复制代码
/**
 * 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!=nullptr && fast->next!=nullptr){
            slow=slow->next;
            fast=fast->next->next;
            if(slow==fast){
                ListNode* t1=fast;
                ListNode* t2=head;
                while(t1!=t2){
                    t1=t1->next;
                    t2=t2->next;
                }
                return t1;
            }
        }
        return nullptr;
    }
};
java 复制代码
/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public 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(fast==slow){
                ListNode t1=fast;
                ListNode t2=head;
                while(t1!=t2){
                    t1=t1.next;
                    t2=t2.next;
                }
                return t1;
            }
        }
        return null;
    }
}

1.8 从尾到头打印链表

https://www.acwing.com/problem/content/18/

代码实现(C++/Java)

cpp 复制代码
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    vector<int> printListReversingly(ListNode* head) {
        vector<int> res;
        while(head!=nullptr){
            res.push_back(head->val);
            head=head->next;
        }
        return vector<int> (res.rbegin(),res.rend());
    }
};
java 复制代码
/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public int[] printListReversingly(ListNode head) {
        ArrayList<Integer> res=new ArrayList<>();
        while(head!=null){
            res.add(head.val);
            head=head.next;
        }
        int[]ress=new int[res.size()];
        for(int i=0;i<res.size();i++){
            ress[i]=res.get(res.size()-1-i);
        }
        return ress;
    }
}

1.9 在O(1)时间删除链表结点

https://www.acwing.com/problem/content/85/

代码实现(C++/Java)

cpp 复制代码
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    void deleteNode(ListNode* node) {
        //将下一个节点的值复制到当前节点,然后删除下一个节点
        auto p=node->next;
        node->val=p->val;
        node->next=p->next;
    }
};
java 复制代码
/**J
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public void deleteNode(ListNode node) {
        ListNode p=node.next;
        node.val=p.val;
        node.next=p.next;
    }
}

1.10 合并两个排序的链表

https://www.acwing.com/problem/content/34/

代码实现(C++/Java)

cpp 复制代码
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* merge(ListNode* l1, ListNode* l2) {
        ListNode* dummy=new ListNode(0);
        ListNode* cur=dummy;
        while(l1!=nullptr && l2!=nullptr){
            if(l1->val<l2->val){
                cur->next=l1;
                l1=l1->next;
            } else {
                cur->next=l2;
                l2=l2->next;
            }
            cur=cur->next;
        }
        if(l1==nullptr){
            cur->next=l2;
        } else {
            cur->next=l1;
        }
        return dummy->next;
    }
};
java 复制代码
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode merge(ListNode l1, ListNode l2) {
        ListNode dummy=new ListNode(0);
        ListNode cur=dummy;
        while(l1!=null && l2!=null){
            if(l1.val<l2.val){
                cur.next=l1;
                l1=l1.next;
            } else {
                cur.next=l2;
                l2=l2.next;
            }
            cur=cur.next;
        }
        if(l1==null) cur.next=l2;
        else cur.next=l1;
        return dummy.next;
    }
}

1.11 删除链表中的重复节点

https://www.acwing.com/problem/content/27/

代码实现(C++/Java)

cpp 复制代码
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* deleteDuplication(ListNode* head) {
        ListNode* dummy=new ListNode(0);
        dummy->next=head;
        auto p=dummy;
        while(p->next!=nullptr){
            if(p->next->next!=nullptr && p->next->val==p->next->next->val){
                int val=p->next->val;
                while(p->next!=nullptr && p->next->val==val){
                    p->next=p->next->next;
                }
            } else {
                p=p->next;
            }
        }
        return dummy->next;
    }
};
java 复制代码
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode deleteDuplication(ListNode head) {
        ListNode dummy=new ListNode(0);
        dummy.next=head;
        ListNode p=dummy;
        while(p.next!=null){
            if(p.next.next!=null && p.next.val==p.next.next.val){
                int val=p.next.val;
                while(p.next!=null && p.next.val==val){
                    p.next=p.next.next;
                }
            } else {
                p=p.next;
            }
        }
        return dummy.next;
    }
}

2.栈与队列

2.1 用栈实现队列

232. 用栈实现队列 - 力扣(LeetCode)

代码实现(C++/Java)

cpp 复制代码
class MyQueue {
public:
    stack<int> input;
    stack<int> output;
    MyQueue() {
        
    }
    
    void push(int x) {
        input.push(x);
    }
    
    int pop() {
        if(output.empty()){
            while(!input.empty()){
                output.push(input.top());
                input.pop();
            }
        }
        int res=output.top();
        output.pop();
        return res;
    }
    
    int peek() {
        int res=pop();
        output.push(res);
        return res;
    }
    
    bool empty() {
        return input.empty() && output.empty();
    }
};
java 复制代码
class MyQueue {
    Stack<Integer> input;
    Stack<Integer> output;
    public MyQueue() {
        input=new Stack<>();
        output=new Stack<>();
    }
    
    public void push(int x) {
        input.push(x);
    }
    
    public int pop() {
        if(output.isEmpty()){
            while(!input.isEmpty()){
                output.push(input.pop());
            }
        }
        return output.pop();
    }
    
    public int peek() {
        int res=this.pop();
        output.push(res);
        return res;
    }
    
    public boolean empty() {
        return input.isEmpty()&& output.isEmpty();
    }
}

2.2 用队列实现栈

225. 用队列实现栈 - 力扣(LeetCode)

代码实现(C++/Java)

cpp 复制代码
class MyStack {
public:
    queue<int> q1;
    queue<int> q2;
    MyStack() {
        
    }
    
    void push(int x) {
        q1.push(x);
    }
    
    int pop() {
        int size=q1.size();
        for(int i=0;i<size-1;i++){
            q2.push(q1.front());
            q1.pop();
        }
        int res=q1.front();
        q1.pop();
        swap(q1,q2);
        return res;
    }
    
    int top() {
        int res=pop();
        push(res);
        return res;
    }
    
    bool empty() {
        return q1.empty();
    }
};
java 复制代码
class MyStack {
    Queue<Integer> q1;
    Queue<Integer> q2;

    public MyStack() {
        q1=new LinkedList<>();
        q2=new LinkedList<>();
    }
    
    public void push(int x) {
        q1.offer(x);
    }
    
    public int pop() {
        int size=q1.size();
        //q1中留一个元素
        for(int i=0;i<size-1;i++) q2.offer(q1.poll());
        int res=q1.poll();
        //q2重新回q1
        Queue<Integer> t=q1;
        q1=q2;
        q2=t;
        return res;
    }
    
    public int top() {
        int res=this.pop();
        this.push(res);
        return res;
    }
    
    public boolean empty() {
        return q1.isEmpty();
    }
}

2.3 有效的括号

20. 有效的括号 - 力扣(LeetCode)

代码实现(C++/Java)

cpp 复制代码
class Solution {
public:
    bool isValid(string s) {
        stack<char> stk;
        for(int i=0;s[i];i++){
            char c=s[i];
            if(c=='(') stk.push(')');
            else if(c=='{') stk.push('}');
            else if(c=='[') stk.push(']');
            else if(stk.empty() || stk.top()!=c) return false;
            else stk.pop();
        }
        return stk.empty();
    }
};
java 复制代码
class Solution {
    public boolean isValid(String s) {
        Stack<Character> stk=new Stack<>();
        for(int i=0;i<s.length();i++){
            char c=s.charAt(i);
            if(c=='(') stk.push(')');
            else if(c=='{') stk.push('}');
            else if(c=='[') stk.push(']');
            else if(stk.empty() || stk.peek()!=c) return false;
            else stk.pop();
        }
        return stk.empty();
    }
}

2.4 删除字符串中所有相邻重复项

1047. 删除字符串中的所有相邻重复项 - 力扣(LeetCode)

代码实现(C++/Java)

cpp 复制代码
class Solution {
public:
    string removeDuplicates(string s) {
        string res;//模拟栈
        for(char c:s){
            if(res.empty() || res.back()!=c){
                res.push_back(c);
            } else {
                res.pop_back();
            }
        }
        return res;
    }
};
java 复制代码
class Solution {
    public String removeDuplicates(String s) {
        StringBuilder sb=new StringBuilder();//模拟栈
        char[] ch=s.toCharArray();
        for(char c:ch){
            if(sb.length()==0 || sb.charAt(sb.length()-1)!=c){
                sb.append(c);
            } else {
                sb.deleteCharAt(sb.length()-1);
            }
        }
        return sb.toString();
    }
}

2.5 逆波兰表达式求值

150. 逆波兰表达式求值 - 力扣(LeetCode)

代码实现(C++/Java)

cpp 复制代码
class Solution {
public:
    int evalRPN(vector<string>& tokens) {
        stack<int> stk;
        for(auto &t:tokens){
            if(t=="+"){
                int t1=stk.top();
                stk.pop();
                int t2=stk.top();
                stk.pop();
                stk.push(t1+t2);
            } else if(t=="-"){
                int t1=stk.top();
                stk.pop();
                int t2=stk.top();
                stk.pop();
                stk.push(t2-t1);
            } else if(t=="*"){
                int t1=stk.top();
                stk.pop();
                int t2=stk.top();
                stk.pop();
                stk.push(t1*t2);
            } else if(t=="/"){
                int t1=stk.top();
                stk.pop();
                int t2=stk.top();
                stk.pop();
                stk.push(t2/t1);
            } else {
                stk.push(stoi(t));
            }
        }
        return stk.top();
    }
};
java 复制代码
class Solution {
    public int evalRPN(String[] tokens) {
        Stack<Integer> stk=new Stack<>();
        for(int i=0;i<tokens.length;i++){
            if(tokens[i].equals("+")){
                int t1=stk.pop();
                int t2=stk.pop();
                stk.push(t1+t2);
            } else if(tokens[i].equals("-")){
                int t1=stk.pop();
                int t2=stk.pop();
                stk.push(t2-t1); //顺序   
            } else if(tokens[i].equals("*")){
                int t1=stk.pop();
                int t2=stk.pop();
                stk.push(t1*t2);  
            } else if(tokens[i].equals("/")){
                int t1=stk.pop();
                int t2=stk.pop();
                stk.push(t2/t1);   //顺序 
            } else {
                stk.push(Integer.valueOf(tokens[i]));
            }
        }
        return stk.pop();
    }
}

2.6 滑动窗口最大值

239. 滑动窗口最大值 - 力扣(LeetCode)

代码实现(C++/Java)

cpp 复制代码
class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        vector<int> res;
        int n=nums.size();
        deque<int> q;
        //维护单调递减队列
        for(int i=0;i<n;i++){
            if(!q.empty() && q.front()<=i-k){
                q.pop_front();
            }
            while(!q.empty() && nums[i]>=nums[q.back()]){
                q.pop_back();
            }
            q.push_back(i);
            if(i>=k-1) res.push_back(nums[q.front()]);
        }
        return res;

    }
};
java 复制代码
class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        int n=nums.length;
        int[] res=new int[n-k+1];
        Deque<Integer> q=new ArrayDeque<>();
        int cnt=0;
        //维护单调递减队列
        for(int i=0;i<n;i++){
            if(!q.isEmpty() && q.peekFirst()<=i-k){
                q.pollFirst();
            }
            while(!q.isEmpty() && nums[i]>=nums[q.peekLast()]){
                q.pollLast();
            }
            q.offer(i);
            if(i>=k-1){
                res[cnt++]=nums[q.peekFirst()];
            }
        }
        return res;
    }
}

3.二叉树

前序:根->左->右 中序:左->根->右 后序:左->右->根

3.1 二叉树前序遍历

144. 二叉树的前序遍历 - 力扣(LeetCode)

3.1.1 递归实现

cpp 复制代码
class Solution {
public:
    void preOrder(TreeNode* node,vector<int>& res){
        if(node==nullptr) return;
        res.push_back(node->val);
        preOrder(node->left,res);
        preOrder(node->right,res);
    }
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> res;
        preOrder(root,res);
        return res;
    }
};

3.1.2 非递归实现

cpp 复制代码
class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> res;
        stack<TreeNode*> stk;
        if(root==nullptr) return res;
        stk.push(root);
        while(!stk.empty()){
            TreeNode* node=stk.top();
            stk.pop();
            res.push_back(node->val);
            if(node->right!=nullptr) stk.push(node->right);
            if(node->left!=nullptr) stk.push(node->left);
        }
        return res;

    }
};
java 复制代码
class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> res=new ArrayList<>();
        Stack<TreeNode> stk=new Stack<>();
        if(root==null) return res;
        stk.push(root);
        while(!stk.isEmpty()){
            TreeNode node=stk.pop();
            res.add(node.val);
            if(node.right!=null) stk.push(node.right);
            if(node.left!=null) stk.push(node.left);
        }
        return res;
    }
}

3.2 二叉树后序遍历

145. 二叉树的后序遍历 - 力扣(LeetCode)

3.2.1 递归实现

cpp 复制代码
class Solution {
public:
    void afterOrder(TreeNode* node,vector<int>& res){
        if(node==nullptr) return;
        afterOrder(node->left,res);
        afterOrder(node->right,res);
        res.push_back(node->val);
    }
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> res;
        afterOrder(root,res);
        return res;
    }
};

3.2.2 非递归实现

cpp 复制代码
class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> res;
        stack<TreeNode*> stk;
        if(root==nullptr) return res;
        stk.push(root);
        //根->右->左 反转 左->右->根
        while(!stk.empty()){
            TreeNode* node=stk.top();
            stk.pop();
            res.push_back(node->val);
            if(node->left!=nullptr) stk.push(node->left);
            if(node->right!=nullptr) stk.push(node->right);
        }
        reverse(res.begin(),res.end());
        return res;
    }
};
java 复制代码
class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        //根->右->左 反转 左->右->根
        ArrayList<Integer> res=new ArrayList<>();
        Stack<TreeNode> stk=new Stack<>();
        if(root==null) return res;
        stk.push(root);
        while(!stk.isEmpty()){
            TreeNode node=stk.pop();
            res.add(node.val);
            if(node.left!=null) stk.push(node.left);
            if(node.right!=null) stk.push(node.right);
        }
        Collections.reverse(res);
        return res;
    }
}

3.3 二叉树中序遍历

94. 二叉树的中序遍历 - 力扣(LeetCode)

3.3.1 递归实现

cpp 复制代码
class Solution {
public:
    void midOrder(TreeNode* node,vector<int>& res){
        if(node==nullptr) return;
        midOrder(node->left,res);
        res.push_back(node->val);
        midOrder(node->right,res);
    }
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> res;
        midOrder(root,res);
        return res;
    }
};

3.3.2 非递归实现

cpp 复制代码
class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> res;
        stack<TreeNode*> stk;
        TreeNode* cur=root;
        while(cur!=nullptr || !stk.empty()){
            if(cur!=nullptr){
                stk.push(cur);
                cur=cur->left;
            }else {
                cur=stk.top();
                stk.pop();
                res.push_back(cur->val);
                cur=cur->right;
            }
        }
        return res;
    }
};
java 复制代码
class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> res=new ArrayList<>();
        Stack<TreeNode> stk=new Stack<>();
        TreeNode cur=root;
        while(cur!=null || !stk.isEmpty()){
            if(cur!=null){
                stk.push(cur);
                cur=cur.left;
            } else {
                cur=stk.pop();
                res.add(cur.val);
                cur=cur.right;
            }
        }
        return res;
    }
}

3.4 二叉树的层序遍历

102. 二叉树的层序遍历 - 力扣(LeetCode)

代码实现(C++/Java)

cpp 复制代码
class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        vector<vector<int>> res;
        queue<TreeNode*> q;
        if(root!=nullptr) q.push(root);
        while(!q.empty()){
            int size=q.size();
            vector<int> level;
            for(int i=0;i<size;i++){
                TreeNode* node=q.front();
                q.pop();
                level.push_back(node->val);
                if(node->left!=nullptr) q.push(node->left);
                if(node->right!=nullptr) q.push(node->right);
            }
            res.push_back(level);
        }
        return res;
    }
};
java 复制代码
class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> res=new ArrayList<>();
        Queue<TreeNode> q=new LinkedList<>();
        if(root!=null) q.offer(root);
        while(!q.isEmpty()){
            int size=q.size();
            List<Integer> level=new ArrayList<>();
            for(int i=1;i<=size;i++){
                TreeNode node=q.poll();
                level.add(node.val);
                if(node.left!=null) q.offer(node.left);
                if(node.right!=null) q.offer(node.right);
            }
            res.add(level);
        }
        return res;
    }
}

3.5 反转二叉树

LCR 144. 翻转二叉树 - 力扣(LeetCode)

代码实现(C++/Java)

cpp 复制代码
class Solution {
public:
    TreeNode* flipTree(TreeNode* root) {
        if(root==nullptr) return root;
        TreeNode* t=root->left;
        root->left=root->right;
        root->right=t;
        flipTree(root->left);
        flipTree(root->right);
        return root;
    }
};
java 复制代码
class Solution {
    public TreeNode flipTree(TreeNode root) {
        if(root==null) return root;
        TreeNode t=root.left;
        root.left=root.right;
        root.right=t;
        flipTree(root.left);
        flipTree(root.right);
        return root;
    }
}

3.6 对称二叉树

101. 对称二叉树 - 力扣(LeetCode)

代码实现(C++/Java)

cpp 复制代码
class Solution {
public:
    bool cp(TreeNode* left,TreeNode* right){
        if(left==nullptr && right!=nullptr) return false;
        else if(left!=nullptr && right==nullptr) return false;
        else if(left==nullptr && right==nullptr) return true;
        else if(left->val!=right->val) return false;
        else return cp(left->left,right->right) && cp(left->right,right->left);
    }
    bool isSymmetric(TreeNode* root) {
        if(root==nullptr) return true;
        return cp(root->left,root->right);
    }
};
java 复制代码
class Solution {
    public boolean isSymmetric(TreeNode root) {
        if(root==null) return true;
        return cp(root.left,root.right);
    }
    public static boolean cp(TreeNode left,TreeNode right){
        if(left==null && right!=null) return false;
        else if(left!=null && right==null) return false;
        else if(left==null && right==null) return true;
        else if(left.val!=right.val) return false;
        else return cp(left.left,right.right) && cp(left.right,right.left);
    }
}

3.7 二叉树的最大深度

//高度:到叶子节点的距离 后序 //深度;到根节点的距离 前序

104. 二叉树的最大深度 - 力扣(LeetCode)

代码实现(C++/Java)

cpp 复制代码
class Solution {
public:
    int maxDepth(TreeNode* root) {
        if(root==nullptr) return 0;
        int l=maxDepth(root->left);
        int r=maxDepth(root->right);
        int m=max(l,r)+1;
        return m;
    }
};
java 复制代码
class Solution {
    public int maxDepth(TreeNode root) {
        if(root==null) return 0;
        int l=maxDepth(root.left);
        int r=maxDepth(root.right);
        int m=Math.max(l,r)+1;
        return m;
    }
}

3.8 二叉树的最小深度

111. 二叉树的最小深度 - 力扣(LeetCode)

代码实现(C++/Java)

cpp 复制代码
class Solution {
public:
    int minDepth(TreeNode* root) {
        if(root==nullptr) return 0;
        int l=minDepth(root->left);
        int r=minDepth(root->right);
        int res=0;
        if(root->left!=nullptr && root->right==nullptr) return l+1;
        if(root->right!=nullptr && root->left==nullptr) return r+1;
        res=min(l,r)+1;
        return res;
    }
};
java 复制代码
 //根节点到叶子节点的最小距离
class Solution {
    public int minDepth(TreeNode root) {
        if(root==null) return 0;
        int l=minDepth(root.left);
        int r=minDepth(root.right);
        int res=0;
        if(root.left!=null && root.right==null) return l+1;
        if(root.right!=null && root.left==null) return r+1;
        res=Math.min(l,r)+1;
        return res;
    }
}

3.9 完全二叉树的节点个数

222. 完全二叉树的节点个数 - 力扣(LeetCode)

代码实现(C++/Java)

cpp 复制代码
class Solution {
public:
    int countNodes(TreeNode* root) {
        if(root==nullptr) return 0;
        int l=countNodes(root->left);
        int r=countNodes(root->right);
        return l+r+1;
    }
};
java 复制代码
class Solution {
    public int countNodes(TreeNode node) {
        if(node==null) return 0;
        int l=countNodes(node.left);
        int r=countNodes(node.right);
        return l+r+1;
    }
}

3.10 平衡二叉树

110. 平衡二叉树 - 力扣(LeetCode)

代码实现(C++/Java)

cpp 复制代码
class Solution {
public:
    //返回以该节点为根节点的⼆叉树的⾼度,如果不是平衡⼆叉树了则返回-1
    int getHeight(TreeNode* node){
        if(node==nullptr) return 0;
        int l=getHeight(node->left);
        if(l==-1) return -1;
        int r=getHeight(node->right);
        if(r==-1) return -1;
        int res=-2;
        if(abs(r-l)>1) res=-1;
        else res=max(l,r)+1;
        return res;
    }
    bool isBalanced(TreeNode* root) {
        //平衡二叉树:任意节点的左右子树高度差绝对值不超过1
        if(getHeight(root)==-1) return false;
        else return true;
    }

};
java 复制代码
class Solution {
    //平衡二叉树:任意节点的左右子树高度差绝对值不超过1
    public boolean isBalanced(TreeNode root) {
        if(getHeight(root)==-1){
            return false;
        } else {
            return true;
        }
    }
    //返回以该节点为根节点的⼆叉树的⾼度,如果不是平衡⼆叉树了则返回-1
    public static int getHeight(TreeNode node){
        if(node==null) return 0;
        int l=getHeight(node.left);
        if(l==-1) return -1;
        int r=getHeight(node.right);
        if(r==-1) return -1;
        int res=-2;
        if(Math.abs(r-l)>1){
            res=-1;
        }else {
            res=Math.max(l,r)+1;
        }
        return res;
    }
}

3.11 左叶子之和

404. 左叶子之和 - 力扣(LeetCode)

代码实现(C++/Java)

cpp 复制代码
class Solution {
public:
    int sumOfLeftLeaves(TreeNode* root) {
        if(root==nullptr) return 0;
        int sum=0;
        //当前节点的左孩子是不是左叶子
        if(root->left!=nullptr && root->left->left==nullptr && root->left->right==nullptr){
            sum+=root->left->val;
        } else {
            sum+=sumOfLeftLeaves(root->left);
        }
        sum+=sumOfLeftLeaves(root->right);
        return sum;
    }
};
java 复制代码
class Solution {
    public int sumOfLeftLeaves(TreeNode root) {
       if(root==null) return 0;
       int sum=0;
       if(root.left!=null && root.left.left==null && root.left.right==null){
            sum+=root.left.val;
       } else {
            sum+=sumOfLeftLeaves(root.left);
       }
       sum+=sumOfLeftLeaves(root.right);
       return sum;
    }
}

3.12 二叉树的所有路径

257. 二叉树的所有路径 - 力扣(LeetCode)

代码实现(C++/Java)

cpp 复制代码
class Solution {
public:
    void dfs(TreeNode* cur,vector<int> &path,vector<string> &res){
        if(cur==nullptr) return;
        path.push_back(cur->val);
        if(cur->left==nullptr && cur->right==nullptr){
            res.push_back(build(path));
        }else {
            dfs(cur->left,path,res);
            dfs(cur->right,path,res);
        } 
        path.pop_back();
    }
    string build(vector<int> &path){
        string sb;
        for(int i=0;i<path.size();i++){
            sb+=to_string(path[i]);
            if(i!=path.size()-1) sb+="->";
        }
        return sb;
    }
    vector<string> binaryTreePaths(TreeNode* root) {
        vector<string> res;
        vector<int> path;
        dfs(root,path,res);
        return res;
    }
};
java 复制代码
class Solution {
    public List<String> binaryTreePaths(TreeNode root) {
        List<String> result=new ArrayList<>();
        List<Integer> path=new ArrayList<>();
        dfs(root,path,result);
        return result;
    }
    public static void dfs(TreeNode cur,List<Integer> path,List<String> result){
        if(cur==null) return;
        path.add(cur.val);
        if(cur.left==null && cur.right==null){
            result.add(build(path));
        } else {
            dfs(cur.left,path,result);
            dfs(cur.right,path,result);
        }
        path.remove(path.size()-1);
    }

    public static String build(List<Integer> path){
        StringBuilder sb=new StringBuilder();
        for(int i=0;i<path.size();i++){
            sb.append(path.get(i));
            if(i!=path.size()-1) sb.append("->");
        }
        
        return sb.toString();
    }
}

3.13 找树左下角的值

513. 找树左下角的值 - 力扣(LeetCode)
代码实现(C++/Java)

cpp 复制代码
class Solution {
public:
    int findBottomLeftValue(TreeNode* root) {
        queue<TreeNode*> q;
        if(root!=nullptr) q.push(root);
        int res=-1;
        while(!q.empty()){
            int size=q.size();
            for(int i=0;i<size;i++){
                TreeNode* node=q.front();
                q.pop();
                if(i==0) res=node->val;
                if(node->left!=nullptr) q.push(node->left);
                if(node->right!=nullptr) q.push(node->right);
            }
        }
        return res;

    }
};
java 复制代码
class Solution {
    public int findBottomLeftValue(TreeNode root) {
        Queue<TreeNode> q=new LinkedList<>();
        if(root!=null) q.offer(root);
        int res=-1;
        while(!q.isEmpty()){
            int size=q.size();
            for(int i=0;i<size;i++){
                TreeNode node=q.poll();
                if(i==0) res=node.val;
                if(node.left!=null) q.offer(node.left);
                if(node.right!=null) q.offer(node.right);
            }
        }
        return res;
    }
}

3.14 路径总和

112. 路径总和 - 力扣(LeetCode)

代码实现(C++/Java)

cpp 复制代码
class Solution {
public:
    bool fun(TreeNode* cur,int cnt){
        if(cur->left==nullptr && cur->right==nullptr && cnt==0){
            return true;
        }
        if(cur->left==nullptr && cur->right==nullptr && cnt!=0) return false;
        if(cur->left!=nullptr){
            if(fun(cur->left,cnt-cur->left->val)){
                return true;
            }
        }
        if(cur->right!=nullptr){
            if(fun(cur->right,cnt-cur->right->val)){
                return true;
            }
        }
        return false;

    }
    bool hasPathSum(TreeNode* root, int targetSum) {
        if(root==nullptr) return false;
        return fun(root,targetSum-root->val);
    }
};
java 复制代码
class Solution {
    public boolean hasPathSum(TreeNode root, int targetSum) {
        if(root==null) return false;
        return fun(root,targetSum-root.val);
    }
    public static boolean fun(TreeNode cur,int cnt){
        if(cur.left==null && cur.right==null && cnt==0){
            return true;
        }
        if(cur.left==null && cur.right==null && cnt!=0){
            return false;
        }
        if(cur.left!=null){
            if(fun(cur.left,cnt-cur.left.val)){
                return true;
            }
        }
        if(cur.right!=null){
            if(fun(cur.right,cnt-cur.right.val)){
                return true;
            }
        }
        return false;

    }
}

3.15 路径总和2

113. 路径总和 II - 力扣(LeetCode)

代码实现(C++/Java)

cpp 复制代码
class Solution {
public:
    void dfs(TreeNode* cur,int cnt,vector<int>& path,vector<vector<int>>& res){
        if(cur==nullptr) return;
        path.push_back(cur->val);
        cnt-=cur->val;
        if(cur->left==nullptr && cur->right==nullptr && cnt==0){
           res.push_back(path);
        } else {
            dfs(cur->left,cnt,path,res);
            dfs(cur->right,cnt,path,res);
        }
        path.pop_back();
    }
    vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
        vector<vector<int>> res;
        vector<int> path;
        dfs(root,targetSum,path,res);
        return res;
    }
};
java 复制代码
class Solution {
    public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
        List<List<Integer>> res=new ArrayList<>();
        List<Integer> path=new ArrayList<>();
        dfs(root,targetSum,path,res);
        return res;
    }
    public static void dfs(TreeNode cur,int cnt,List<Integer> path,List<List<Integer>> res){
        if(cur==null) return;
        path.add(cur.val);
        cnt-=cur.val;
        if(cur.left==null && cur.right==null && cnt==0){
            // 关键:需要添加 path 的一个副本,而不是 path 本身
            res.add(new ArrayList<>(path));
        }else {
            dfs(cur.left,cnt,path,res);
            dfs(cur.right,cnt,path,res);
        }
        path.remove(path.size()-1);
    }
}

3.16 路径总和3

437. 路径总和 III - 力扣(LeetCode)

代码实现(C++/Java)

cpp 复制代码
class Solution {
public:
    int dfs(TreeNode* node,long long targetSum){
        if(node==nullptr) return 0;
        int cnt=0;
        if(node->val==targetSum) cnt++;
        cnt+=dfs(node->left,targetSum-node->val);
        cnt+=dfs(node->right,targetSum-node->val);
        return cnt;
    }
    int pathSum(TreeNode* root, int targetSum) {
        if(root==nullptr) return 0;
        int res=dfs(root,targetSum);
        res+=pathSum(root->left,targetSum);
        res+=pathSum(root->right,targetSum);
        return res;
    }
};
java 复制代码
class Solution {
    public int pathSum(TreeNode root, int targetSum) {
        if(root==null) return 0;
        int res=dfs(root,targetSum);
        res+=pathSum(root.left,targetSum);
        res+=pathSum(root.right,targetSum);
        return res;
    }
    public static int dfs(TreeNode node,long targetSum){
        if(node==null) return 0;
        int cnt=0;
        if(node.val==targetSum) cnt++;
        cnt+=dfs(node.left,targetSum-node.val);
        cnt+=dfs(node.right,targetSum-node.val);
        return cnt;
    }
}
相关推荐
皮皮哎哟6 小时前
数据结构:嵌入式常用排序与查找算法精讲
数据结构·算法·排序算法·二分查找·快速排序
堕2747 小时前
java数据结构当中的《排序》(一 )
java·数据结构·排序算法
2302_813806227 小时前
【嵌入式修炼:数据结构篇】——数据结构总结
数据结构
Wei&Yan8 小时前
数据结构——顺序表(静/动态代码实现)
数据结构·c++·算法·visual studio code
long3168 小时前
Aho-Corasick 模式搜索算法
java·数据结构·spring boot·后端·算法·排序算法
张张努力变强11 小时前
C++ STL string 类:常用接口 + auto + 范围 for全攻略,字符串操作效率拉满
开发语言·数据结构·c++·算法·stl
wWYy.11 小时前
数组快排 链表归并
数据结构·链表
李斯啦果11 小时前
【PTA】L1-019 谁先倒
数据结构·算法
Mr Xu_1 天前
告别硬编码:前端项目中配置驱动的实战优化指南
前端·javascript·数据结构