【算法题】牛客研发最爱考[1 - 10]

刷题链接

反转链表

递推实现

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
    
    
public:
    ListNode* ReverseList(ListNode* pHead) {
    
    
        ListNode *pre = NULL, *cur = pHead;
        while(cur)
        {
    
    
            ListNode *next = cur->next;
            cur->next = pre;
            pre = cur, cur = next;
        }
        return pre;
    }
};

递归

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
    
    
public:
    ListNode* ReverseList(ListNode* pHead) {
    
    
        if(!pHead || !pHead->next) return pHead;
        ListNode *tail = ReverseList(pHead->next);
        pHead->next->next = pHead;
        pHead->next = NULL;
        return tail;
    }
};

排序

快速排序

class Solution {
    
    
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 将给定数组排序
     * @param arr int整型vector 待排序的数组
     * @return int整型vector
     */
    vector<int> MySort(vector<int>& arr) {
    
    
        // write code here
        int n = arr.size();
        quick_sort(arr,0,n - 1);
        return arr;
    }
    
    void quick_sort(vector<int> &q,int l,int r)
    {
    
    
        if(l >= r) return;
        int x = q[l + r >> 1],i = l - 1,j = r + 1;
        while(i < j)
        {
    
    
            do i ++; while(q[i] < x);
            do j --; while(q[j] > x);
            if(i < j) swap(q[i],q[j]);
        }
        quick_sort(q, l, j);
        quick_sort(q, j + 1, r);
    }
};

归并排序

class Solution {
    
    
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 将给定数组排序
     * @param arr int整型vector 待排序的数组
     * @return int整型vector
     */
    vector<int> temp;
    vector<int> MySort(vector<int>& arr) {
    
    
        // write code here
        int n = arr.size();
        temp = vector<int>(n);
        merge_sort(arr,0,n - 1);
        return arr;
    }
   
    void merge_sort(vector<int> &q,int l,int r)
    {
    
    
        if(l >= r) return;
        int mid = l + r >> 1;
        merge_sort(q,l,mid),merge_sort(q,mid + 1,r);
        
        int i = l,j = mid + 1,k = 0;
        while(i <= mid && j<= r)
        {
    
    
            if(q[i] <= q[j]) temp[k ++ ] =  q[i ++ ];
            else temp[k ++ ] = q[j ++ ];
        }
        while(i <= mid) temp[k ++ ] = q[i ++];
        while(j <= r) temp[k ++ ] = q[j ++ ];
        
        for(int i =l,j = 0;i <= r;i ++ ,j ++ ) q[i] = temp[j];
    }
};

设计LRU缓存结构

一个双链表 + 一个哈希表

#include <unordered_map>

class Solution {
    
    
public:
    /**
     * lru design
     * @param operators int整型vector<vector<>> the ops
     * @param k int整型 the k
     * @return int整型vector
     */
    
    struct Node{
    
    
        int key,val;
        Node *left, *right;
        Node():key(0),val(0),left(NULL),right(NULL){
    
    }
    };
    
    Node *head,*tail;
    unordered_map<int,Node*> hash;
    int tot;
    
    void insert(Node *p) // 头插法,最不常用在尾
    {
    
    
        p->left = head,p->right = head->right;
        head->right->left = p, head->right = p;
    }
    
    void remove(Node *p)
    {
    
    
        p->left->right = p->right, p->right->left = p->left;
    }
    
    vector<int> LRU(vector<vector<int> >& operators, int k) {
    
    
        // write code here
        tot = 0;
        head = new Node(); tail = new Node(); // 初始化头尾节点
        head->right = tail,tail->left = head;
        vector<int> res;
        
        for(auto c : operators)
        {
    
    
            int op = c[0];
            if(op == 1)
            {
    
    
                int key = c[1], val = c[2];
                if(hash[key])
                {
    
    
                    Node *p = hash[key];
                    remove(p);
                    p->val = val;
                    insert(p);
                }
                else
                {
    
    
                    if(tot == k)
                    {
    
    
                        Node *p = tail->left;
                        remove(p);
                        hash.erase(p->key);
                        tot --;
                        delete p;
                    }
                    
                    Node *p = new Node();
                    p->val = val, p->key = key;
                    hash[key] = p;
                    tot ++;
                    insert(p);
                }
            }
            else
            {
    
    
                int key = c[1];
                if(hash[key])
                {
    
    
                    Node *p =hash[key];
                    res.push_back(p->val);
                    remove(p);
                    insert(p);
                }
                else
                {
    
    
                    res.push_back(-1);
                }
            }
        }
        return res;
    }
};

判断链表中是否有环

空间复杂度O(1),快慢指针。如果没要求空间复杂度,那么哈希表记录是否出现过也可以

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
    
    
public:
    bool hasCycle(ListNode *head) {
    
    
        if(!head || !head->next) return false;
        auto fast = head->next, slow = head;
        while(slow != fast)
        {
    
    
            if(fast == NULL || fast->next == NULL) return false;
            slow = slow->next;
            fast = fast->next->next;
        }
        return true;
    }
};

二叉树的遍历

栈模拟递归遍历。
另外,二叉树的递归遍历可以考虑根右左的遍历顺序,再反转。

/**
 * struct TreeNode {
 *	int val;
 *	struct TreeNode *left;
 *	struct TreeNode *right;
 * };
 */

class Solution {
    
    
public:
    /**
     * 
     * @param root TreeNode类 the root of binary tree
     * @return int整型vector<vector<>>
     */
    vector<vector<int> > res;
    vector<vector<int> > threeOrders(TreeNode* root) {
    
    
        // write code here
        preorder(root);
        inorder(root);
        postorder(root);
        return res;
    }
    
    void preorder(TreeNode* root)
    {
    
    
        vector<int> ans;
        stack<TreeNode*> stk;
        
        while(root || !stk.empty())
        {
    
    
            while(root){
    
    
                ans.push_back(root->val);
                stk.push(root);
                root = root->left;
            }
            if(!stk.empty())
            {
    
    
                root = stk.top();
                stk.pop();
                root = root->right;
            }
        }
        
        res.push_back(ans);
    }
    
    void inorder(TreeNode* root)
    {
    
    
        vector<int> ans;
        stack<TreeNode*> stk;
        
        while(root || !stk.empty())
        {
    
    
            while(root){
    
    
                stk.push(root);
                root = root->left;
            }
            if(!stk.empty())
            {
    
    
                root = stk.top();
                stk.pop();
                ans.push_back(root->val);
                root = root->right;
            }
        }
        
        res.push_back(ans);
    }
    
    void postorder(TreeNode* root)
    {
    
    
        vector<int> ans;
        stack<TreeNode*> stk;
        TreeNode *cur = root, *pre = NULL;
        
        while(cur || !stk.empty())
        {
    
    
            while(cur){
    
    
                stk.push(cur);
                cur = cur->left;
            }
            cur = stk.top();
            if(cur->right == NULL || cur->right == pre)
            {
    
    
                ans.push_back(cur->val);
                stk.pop();
                pre = cur;
                cur = NULL;
            }else{
    
    
                cur = cur->right;
            }
        }
        
        res.push_back(ans);
    }
    
};

二分查找

如果不存在,返回应该插入的位置
下标从1开始

class Solution {
    
    
public:
    /**
     * 二分查找
     * @param n int整型 数组长度
     * @param v int整型 查找值
     * @param a int整型vector 有序数组
     * @return int整型
     */
    int upper_bound_(int n, int v, vector<int>& a) {
    
    
        // write code here
        int l = 0,r = n;
        while(l < r)
        {
    
    
            int mid = l + r >> 1;
            if(a[mid] >= v) r = mid;
            else l = mid + 1;
        }
        return r + 1;
    }
};

最小的K个数

堆排,时间复杂度 O ( n l o g k ) O(nlogk) O(nlogk)

class Solution {
    
    
public:
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
    
    
        priority_queue<int> q;
        for(auto c : input)
        {
    
    
            q.push(c);
            if(q.size() > k) q.pop();
        }
        vector<int> res;
        if(k > q.size()) return res;
        while(q.size())
        {
    
    
            res.push_back(q.top());
            q.pop();
        }
        return res;
    }
};

快速选择算法nth_element(),时间复杂度 O ( n ) O(n) O(n)

class Solution {
    
    
public:
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
    
    
        if(k > input.size()) return {
    
    };
        nth_element(input.begin(),input.begin() + k - 1,input.end());
        
        vector<int> res;
        for(int i = 0;i < k;i ++) res.push_back(input[i]);
        return res;
    }
};

快速排序模板实现快速选择算法nth_element()

class Solution {
    
    
public:
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
    
    
        if(k > input.size()) return {
    
    };
        //nth_element(input.begin(),input.begin() + k - 1,input.end());
        quick_sort(input,0,input.size() - 1,k);
        vector<int> res;
        for(int i = 0;i < k;i ++) res.push_back(input[i]);
        return res;
    }
    
    void quick_sort(vector<int> &q,int l,int r,int k)
    {
    
    
        if(l >= r) return;
        int x = q[l + r >> 1], i = l - 1,j = r + 1;
        while(i < j)
        {
    
    
            do i++;while(q[i] < x);
            do j--;while(q[j] > x);
            if(i < j) swap(q[i],q[j]);
        }
        int cnt = j - l + 1;
        if(cnt >= k) quick_sort(q,l,j,k);
        else quick_sort(q,j + 1,r,k - cnt);
    }
};

二叉树的层序遍历

队列bfs

/**
 * struct TreeNode {
 *	int val;
 *	struct TreeNode *left;
 *	struct TreeNode *right;
 * };
 */

class Solution {
    
    
public:
    /**
     * 
     * @param root TreeNode类 
     * @return int整型vector<vector<>>
     */
    vector<vector<int> > res;
    vector<vector<int> > levelOrder(TreeNode* root) {
    
    
        // write code here
        if(!root) return{
    
    };
        bfs(root);
        return res;
    }
    
    void bfs(TreeNode* root)
    {
    
    
        queue<TreeNode*> q;
        q.push(root);
        while(q.size())
        {
    
    
            int n = q.size();
            vector<int> ans;
            while(n -- ){
    
    
                auto t = q.front();
                q.pop();
                ans.push_back(t->val);
                if(t->left) q.push(t->left);
                if(t->right) q.push(t->right);
            }
            res.push_back(ans);
        }
    }
    
};

寻找第K大

nth_element()函数

class Solution {
    
    
public:
    int findKth(vector<int> a, int n, int K) {
    
    
        // write code here‘
        nth_element(a.begin(),a.begin() + n - K ,a.end()); // 是第K大,不是第K小
        return a[n - K];
    }
};

手动实现

class Solution {
    
    
public:
    int findKth(vector<int> a, int n, int K) {
    
    
        // write code here‘
        quick_sort(a,0,n - 1,n - K + 1); // 第K大相等于第n - K小
        return a[n - K];
    }
    
    void quick_sort(vector<int> &q,int l,int r,int k)
    {
    
    
        if(l >= r) return ;
        int x = q[l + r >> 1], i = l - 1,j = r + 1;
        while(i < j)
        {
    
    
            do i ++ ;while(q[i] < x);
            do j -- ;while(q[j] > x);
            if(i < j) swap(q[i],q[j]);
        }
        int cnt = j - l + 1;
        if(cnt >= k) quick_sort(q,l,j,k);
        else quick_sort(q,j + 1,r,k - cnt);
    }
};

跳台阶

递归

class Solution {
    
    
public:
    int jumpFloor(int number) {
    
    
        return dfs(number);
    }
    
    int dfs(int x)
    {
    
    
        if(x == 1 || x == 2) return x;
        return dfs(x - 1) + dfs(x - 2);
    }
};

递推

class Solution {
    
    
public:
    int jumpFloor(int n) {
    
    
        if(n == 1 || n == 2) return n;
        vector<int> f(n + 1);
        f[1] = 1, f[2] = 2;
        for(int i =3;i <= n;i ++ )
            f[i] = f[i - 1] + f[i - 2];
        return f[n];
    }
};

优化空间

class Solution {
    
    
public:
    int jumpFloor(int n) {
    
    
        if(n == 1 || n == 2) return n;
        vector<int> f(n + 1);
        //f[1] = 1, f[2] = 2;
        int a = 1,b = 2, c;
        for(int i =3;i <= n;i ++ ){
    
    
            //f[i] = f[i - 1] + f[i - 2];
            c = a + b;
            a = b, b = c;
        }
        return c;
    }
};

猜你喜欢

转载自blog.csdn.net/weixin_43154149/article/details/113776508