《代码随想录》代码合集


前言

《代码随想录》算法公开课代码合集


数组

二分查找

#include <iostream>
#include <string>
#include<vector>

using namespace std;

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left = 0 ;
        int right = nums.size() -1;
        while (left<=right){
            int mid = (right+left)/2;
            if (target == nums[mid]){
                return mid;
            }
            else if (target > nums[mid]){
                left = mid +1;
            }
            else{
                right = mid -1;
            }
        }
        return -1;
    }
};
int main(void){
    Solution s1;
    int num[5]={1,3,5,6,10};
    int target = 1;
    vector<int> a(num,num+5);
    int result = s1.search(a,target);
    cout<<result<<endl;
}

移除元素

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int count = 0;
        int x = 0;
        // vector<int> t(nums);
        for (int i =0;i<nums.size();i++){
            if (val != nums[i]){
                nums[x]=nums[i];
                count +=1;
                x+=1;
            }
        }
        return count;
    }
};

有序数组的平方

简单的快排

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        vector<int> ans;
        for (int num: nums) {
            ans.push_back(num * num);
        }
        sort(ans.begin(), ans.end());
        return ans;
    }
};

双指针方法

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        int n = nums.size();
        vector<int> a(n);
        int pos = n -1;
        for (int i=0, j = n - 1;i<=j; ){
            if (nums[i]*nums[i]<nums[j]*nums[j]){
                a[pos]=nums[j]*nums[j];
                j--;
            }
            else{
                a[pos]= nums[i]*nums[i];
                i++;
            }
            pos --;
        }
        return a;
    }
};

长度最小的子数组

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int n = nums.size();
        int ans = INT_MAX;
        int start = 0, end = 0;
        int sum = 0;
        while(end<n){
            sum += nums[end];
            while (sum >= target){
                ans =min (ans,end-start+1);
                sum -=nums[start];
                start ++;
                
            }
            end ++;
        }
        return ans == INT_MAX ? 0:ans;
    }
    
};

旋转矩阵

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> mat(n,vector<int>(n,1));
        int tar = n*n;
        int num=1;
        int l = 0,r= n-1,t=0,b=n-1;
        while (num<=tar){
            for (int i = l;i<=r;i++){
                mat[t][i]=num;
                num ++;
            }
            t++;
            for (int j = t;j<=b;j++ ){
                mat[j][r]=num;
                num +=1;
            }
            r--;
            for(int i =r;i>=l;i--){
                mat[b][i]=num;
                num ++;
            }
            b-=1;
            for(int j = b;j>= t;j--){
                mat[j][l]=num;
                num +=1;
            }
            l+=1;
        }
        return mat;
    }
};

链表

移除链表元素

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){};
};
ListNode* createList(const std::vector<int>& values){
    ListNode* head = new ListNode(0);
    ListNode* current = head;
    for (int val :values){
        current->next = new ListNode(val);
        current = current->next;
    }
    return head->next;
}
void printList(ListNode* head){
    while(head != nullptr){
        std::cout<< head->val << "->";
        head = head -> next;
    }
    std::cout <<"nullptr\n";
}
class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        struct ListNode* dummyHead = new ListNode(0,head);
        struct ListNode* temp = dummyHead;
        while (temp->next !=nullptr){
            if(temp->next->val == val){
                temp->next = temp-> next->next;
            }
            else{
                temp = temp ->next;
            }
        }
        return dummyHead->next;
    }
};
int main(void){

    ListNode* list = createList({1,2,6,3,4,5,6});

    Solution solution;
    ListNode* newList = solution.removeElements(list,6);
    printList(newList);

    ListNode* current = list;
    while (current != nullptr)
    {
        ListNode* next = current ->next;
        delete current;
        current = next;
    }
    printList(list);
    return 0 ;

}

设计链表

class MyLinkedList {
public:
    MyLinkedList() {
        this -> size = 0;
        this -> head = new ListNode(0);
    }
    
    int get(int index) {
        if (index < 0 || index >= size){
            return -1;
        }
        ListNode* cur = head;
        for (int i = 0;i<=index;i++){
            cur = cur->next;
        }
        return cur->val;
    }
    
    void addAtHead(int val) {
        addAtIndex(0,val);

    }
    
    void addAtTail(int val) {
        addAtIndex(size,val);
    }
    
    void addAtIndex(int index, int val) {
        if (index > size ){
            return;
        }
        index =max (0,index);
        size++;
        ListNode *pred = head;
        for (int i = 0;i<index;i++){
            pred =pred->next;
        }
        ListNode* toAdd =new ListNode(val);
        toAdd->next = pred->next;
        pred->next = toAdd;


    }
    
    void deleteAtIndex(int index) {
        if (index < 0 || index>= size){
            return;
        }
        size --;
        ListNode* pred = head;
        for(int i = 0;i<index;i++){
            pred = pred->next;
        }
        ListNode* p = pred ->next;
        pred->next = pred->next->next;
        delete p;
    }
private:
    int size;
    ListNode* head;
};

/**
 * 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);
 */

反转链表

/**
 * 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 *cur = head;
        ListNode *pre = nullptr;
        while(cur != nullptr) {
            ListNode* tmp = cur->next; // 暂存后继节点 cur.next
            cur->next = pre;           // 修改 next 引用指向
            pre = cur;                 // pre 暂存 cur
            cur = tmp;                 // cur 访问下一节点
        }
        return pre;
    }
};

两两交换链表中的节点

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* node1 = cur->next;
            ListNode* node2 = cur->next->next->next;
            cur->next = cur->next->next;
            cur->next->next = node1;
            node1->next = node2;
            cur= cur->next->next;

        }
        ListNode* reslut = dummyHead->next;
        delete dummyHead;
        return reslut;

    }
};

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

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode* dummyhead = new ListNode(0);
        dummyhead->next = head;
        ListNode* fast = dummyhead;
        ListNode* slow = dummyhead;
        // int fast = n;
        // int slow = 0;
        for (int i = 0;i<n+1;i++){
            fast=fast->next;
        }
        while(fast != nullptr){
            fast=fast->next;
            slow=slow->next;
        }
        slow->next = slow->next->next;
        return dummyhead->next;

    }
};

环形链表II

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        ListNode *fast = head;
        ListNode *slow = head;
        while (fast != NULL && fast->next != NULL){
            fast = fast->next->next;
            slow = slow->next;
            if (fast == slow){
                ListNode *index1 =fast;
                ListNode *index2 = head;
                while(index1 != index2){
                    index1=index1->next;
                    index2=index2->next;
                };
                return index1;
            }    
        }
        return NULL;
        
    }
};

哈希表

有效的字母异位词

class Solution {
public:
    bool isAnagram(string s, string t) {
        int record[26] = {0};
        for (int i = 0; i < s.size(); i++) {
            record[s[i] - 'a']++;
        }
        for (int i = 0; i < t.size(); i++) {
            record[t[i] - 'a']--;
        }
        for (int i = 0; i < 26; i++) {
            if (record[i] != 0) {
                return false;
            }
        }
        return true;
    }
};

两个数组的交集

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        std::unordered_set<int> result_set;
        std::unordered_set<int> nums_set(nums1.begin(), nums1.end());
        for (int num : nums2) {
            if (nums_set.find(num) != nums_set.end()) {
                result_set.insert(num);
            }
        }
        vector<int> a(result_set.begin(), result_set.end());
        return a;
    }
};

快乐数

class Solution {
public:
    int getSum(int n) {
        int sum = 0;
        while (n) {
            sum += (n % 10) * (n % 10);
            n = n / 10;
        }
        return sum;
    };
    bool isHappy(int n) {
        std::unordered_set<int> re_set;
        while (1) {
            int sum = getSum(n);

            if (re_set.find(sum) != re_set.end()) {
                return false;
            }
            re_set.insert(sum);
            if (sum == 1) {
                return true;
            }

            n = sum;
        }
    }
};

两数之和

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        std::unordered_map<int, int> map;
        for (int i = 0; i < nums.size(); i++) {
            auto iter = map.find(target - nums[i]);
            // std::unordered_map<int, int>::iterator iter = map.find(target - nums[i]);
            if (iter != map.end()) {
                return {iter->second, i};
            }
            map.insert(std::pair<int, int>(nums[i], i));
        }
        return {};
    }
};

四数相加II

#include <vector>
#include <unordered_map>
#include <iostream>

class Solution {
public:
    int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
        std::unordered_map<int, int> map1;
        std::unordered_map<int, int> map2;
        int count = 0;

        // 计算 nums1 和 nums2 的和的频率
        for (int i = 0; i < nums1.size(); i++) {
            for (int j = 0; j < nums2.size(); j++) {
                map1[nums1[i] + nums2[j]]++;
            }
        }

        // 计算 nums3 和 nums4 的和的频率
        for (int i = 0; i < nums3.size(); i++) {
            for (int j = 0; j < nums4.size(); j++) {
                map2[nums3[i] + nums4[j]]++;
            }
        }

        // 遍历 map1,查找在 map2 中对应的负数和的频率,并计算总数
        for (auto it = map1.begin(); it != map1.end(); ++it) {
            int c = it->first;
            if (map2.find(0 - c) != map2.end()) {
                count += it->second * map2[-c];
            }
        }

        return count;
    }
};

// 主函数用于测试
int main() {
    Solution sol;
    vector<int> nums1 = {1, 2};
    vector<int> nums2 = {-2, -1};
    vector<int> nums3 = {-1, 2};
    vector<int> nums4 = {-2, 2};
    int count = sol.fourSumCount(nums1, nums2, nums3, nums4);

    std::cout << "Count: " << count << std::endl;
    return 0;
}

三数之和

双指针解法

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> result;
        sort(nums.begin(), nums.end());

        for (int i = 0; i < nums.size(); i++) {
            if (nums[0] > 0) {
                return result;
            }

            if (i > 0 && nums[i] == nums[i - 1]) {
                continue;
            }
            int left = i + 1;
            int right = nums.size() - 1;
            while (right > left) {
                if (nums[i] + nums[left] + nums[right] > 0)
                    right--;
                else if (nums[i] + nums[left] + nums[right] < 0)
                    left++;
                else {
                    result.push_back(
                        vector<int>{nums[i], nums[left], nums[right]});
                    while (right > left && nums[right] == nums[right - 1])
                        right--;
                    while (right > left && nums[left] == nums[left + 1])
                        left++;

                    right--;
                    left++;
                }
            }
        }
        return result;
    }
};

四数之和

双指针法

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        vector<vector<int>> result;
        sort(nums.begin(), nums.end());
        for (int k = 0; k < nums.size(); k++) {
            if (nums[k] > target && nums[k] >= 0) {
                break;
            }
            if (k > 0 && nums[k] == nums[k - 1]) {
                continue;
            }
            for (int i = k + 1; i < nums.size(); i++) {
                if (nums[k] + nums[i] > target && nums[k] + nums[i] >= 0) {
                    break;
                }
                if (i > k + 1 && nums[i] == nums[i - 1]) {
                    continue;
                }

                int left = i + 1;
                int right = nums.size() - 1;
                while (right > left) {
                    if ((long)nums[k] + nums[i] + nums[left] + nums[right] >
                        target) {
                        right--;
                    } else if ((long)nums[k] + nums[i] + nums[left] +
                                   nums[right] <
                               target) {
                        left++;
                    } else {
                        result.push_back(vector<int>{nums[k], nums[i],
                                                     nums[left], nums[right]});
                        while (right > left && nums[right] == nums[right - 1])
                            right--;
                        while (right > left && nums[left] == nums[left + 1])
                            left++;

                        right--;
                        left++;
                    }
                }
            }
        }
        return result;
    }
};

字符串

反转字符串

在反转链表中,使用了双指针的方法。那么反转字符串依然是使用双指针的方法,只不过对于字符串的反转,其实要比链表简单一些。

class Solution {
public:
    void reverseString(vector<char>& s) {
        for (int i = 0, j = s.size() - 1; i < s.size() / 2; i++, j--) {
            swap(s[i], s[j]);
        }
    }
};

class Solution {
public:
    void reverseString(vector<char>& s) {
        std::reverse(s.begin(),s.end());
    }
};

反转字符串 II

begin()相当于0,end()相当于size,end()返回的自然是最后一个节点的后一个节点,begin() == end()可以直接判空。

class Solution {
public:
    string reverseStr(string s, int k) {
        for (int i = 0; i < s.size(); i += (2 * k)) {
            if (i + k <= s.size()) {
                reverse(s.begin() + i, s.begin() + i + k);
            } else {
                reverse(s.begin() + i, s.end());
            }
        }
        return s;
    }
};

替换数字

其实很多数组填充类的问题,其做法都是先预先给数组扩容待填充后的大小,然后在从后向前进行操作。

#include <iostream>
using namespace std;

int main(){
	string s;
	string n = "number";
	while (cin >> s){
		int sOldIndex = s.size() - 1;
		int count = 0;
		for (int i =0;i<s.size();i++){
			if(s[i]>='0' && s[i] <='9'){
				count ++;
			}
		}
		s.resize(s.size() + count*5);
		int sNewIndex = s.size() -1;
		while (sOldIndex >= 0){
			if(s[sOldIndex]>='0'&&s[sOldIndex]<='9'){
				for(int j = 5;j>=0;j--){
					s[sNewIndex]=n[j];
					sNewIndex--;
				}
			}
			else{
				s[sNewIndex]=s[sOldIndex];
				sNewIndex --;
			}
			sOldIndex --;
		}
		cout<<s<<endl;
	}
}

测试:echo “a1aaaa” | ./test

翻转字符串里的单词

先全部翻转,然后每个单词再翻转

class Solution {
public:
    string reverseWords(string s) {
        std::reverse(s.begin(), s.end());
        int n = s.size();
        int idx = 0;
        for (int start = 0; start < n; start++) {
            if (s[start] != ' ') {
                if (idx != 0)
                    s[idx++] = ' ';

                int end = start;
                while (end < n && s[end] != ' ') {
                    s[idx++] = s[end++];
                }
                reverse(s.begin() + idx - (end - start), s.begin() + idx);

                start = end;
            }
        }
        s.erase(s.begin() + idx, s.end());
        return s;
    }
};

右旋字符串

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

int main(){
	int n;
	std::string s;
	cin >> s;
	cin >> n;
	std::reverse(s.begin(),s.end());
	std::reverse(s.begin(),s.begin()+n);
	std::reverse(s.begin()+n,s.end());
	cout <<s<<endl;
}

实现 strStr()

KMP算法,找匹配项
构建前缀表,即 next表

class Solution {
public:
    void getNext(int* next, const string& s) {
        int j = 0;
        next[0] = 0;
        for (int i = 1; i < s.size(); i++) {
            while (j > 0 && s[i] != s[j]) {
                j = next[j - 1];
            }
            if (s[i] == s[j]) {
                j++;
            }
            next[i] = j;
        }
    }
    int strStr(string haystack, string needle) {
        if (needle.size() == 0) {
            return 0;
        }
        vector<int> next(needle.size());
        getNext(&next[0], needle);
        int j = 0;
        for (int i = 0; i < haystack.size(); i++) {
            while (j > 0 && haystack[i] != needle[j]) {
                j = next[j - 1];
            }
            if (haystack[i] == needle[j]) {
                j++;
            }
            if (j == needle.size()) {
                return (i - needle.size() + 1);
            }
        }
        return -1;
    }
};

重复的子字符串

class Solution {
public:
    bool repeatedSubstringPattern(string s) {
        int n = s.size();
        for (int i = 1; i * 2 <= n; i++) {
            if (n % i == 0) {
                bool match = true;
                for (int j = i; j < n; j++) {
                    if (s[j] != s[j - i]) {
                        match = false;
                        break;
                    }
                }
                if (match) {
                    return true;
                }
            }
        }
        return false;
    }
};

栈和队列

用栈实现队列

class MyQueue {
public:
    stack<int> stIn;
    stack<int> stOut;
    MyQueue() {}

    void push(int x) { stIn.push(x); }

    int pop() {
        if (stOut.empty()) {
            while (!stIn.empty()) {
                stOut.push(stIn.top());
                stIn.pop();
            }
        }
        int result = stOut.top();
        stOut.pop();
        return result;
    }

    int peek() {
        int res = this->pop();
        stOut.push(res);
        return res;
    }

    bool empty() { return stIn.empty() && stOut.empty(); }
};

用队列实现栈

class MyStack {
public:
    queue<int> que;
    MyStack() {}

    void push(int x) { que.push(x); }

    int pop() {
        int size = que.size();
        size--;
        while (size > 0) {
            int fronti = que.front();
            que.pop();
            que.push(fronti);
            size--;
        }
        int result = que.front();
        que.pop();
        return result;
    }

    int top() {
        int size = que.size();
        size--;
        while (size--) {
            que.push(que.front());
            que.pop();
        }
        int result = que.front();
        que.push(que.front());
        que.pop();
        return result;
    }

    bool empty() { return que.empty(); }
};

有效的括号

由于栈结构的特殊性,非常适合做对称匹配类的题目。

class Solution {
public:
    bool isValid(string s) {
        if (s.size() % 2 != 0) {
            return false;
        }
        stack<char> st;
        for (int i = 0; i < s.size(); i++) {
            if (s[i] == '(')
                st.push(')');
            else if (s[i] == '{')
                st.push('}');
            else if (s[i] == '[')
                st.push(']');
            else if (st.empty() || st.top() != s[i])
                return false;
            else
                st.pop();
        }
        return st.empty();
    }
};

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

class Solution {
public:
    string removeDuplicates(string s) {
        stack<char> st;

        for (char cs : s) {
            if (st.empty() || st.top() != cs) {
                st.push(cs);
            } else {
                st.pop();
            }
        }
        string result = "";
        while (!st.empty()) {
            result.push_back(st.top());
            st.pop();
        }
        std::reverse(result.begin(), result.end());
        return result;
    }
};

逆波兰表达式求值

class Solution {
public:
    int evalRPN(vector<string>& tokens) {
        stack<long long> st;
        for (int i = 0; i < tokens.size(); i++) {
            if (tokens[i] == "+" || tokens[i] == "-" || tokens[i] == "*" ||
                tokens[i] == "/") {
                long long num1 = st.top();
                st.pop();
                long long num2 = st.top();
                st.pop();
                if (tokens[i] == "+")
                    st.push(num2 + num1);
                if (tokens[i] == "-")
                    st.push(num2 - num1);
                if (tokens[i] == "*")
                    st.push(num2 * num1);
                if (tokens[i] == "/")
                    st.push(num2 / num1);
            } else {
                st.push(stoll(tokens[i]));
            }
        }
        int result = st.top();
        st.pop();
        return result;
    }
};

滑动窗口最大值

class Solution {
private:
    class MyQueue {
    public:
        deque<int> que;
        void pop(int value) {
            if (!que.empty() && value == que.front()) {
                que.pop_front();
            }
        }
        void push(int value) {
            while (!que.empty() && value > que.back()) {
                que.pop_back();
            }
            que.push_back(value);
        }
        int front() { return que.front(); }
    };

public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        MyQueue que;
        vector<int> result;
        for (int i = 0; i < k; i++) {
            que.push(nums[i]);
        }
        result.push_back(que.front());
        for (int i = k; i < nums.size(); i++) {
            que.pop(nums[i - k]);
            que.push(nums[i]);
            result.push_back(que.front());
        }
        return result;
    }
};

前 K 个高频元素











总结

提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值