【算法题】牛客研发最爱考[21 - 30]

刷题链接

最长公共子串(不是子序列)

class Solution {
    
    
public:
    /**
     * longest common substring
     * @param str1 string字符串 the string
     * @param str2 string字符串 the string
     * @return string字符串
     */
    string LCS(string a, string b) {
    
    
        // write code here
        int n = a.size(), m = b.size();
        vector<vector<int>> f(n + 1,vector<int>(m + 1));
        /*
            f[i][j] : 以a[i]和b[j]结尾的最长公共子串(不是子序列,子串连续)
        */
        int maxlen = 0,idx = 0;
        for(int i = 1;i <= n;i ++ )
             for(int j = 1;j <= m ;j ++ )
             {
    
    
                 if(a[i - 1] == b[j - 1])f[i][j] = f[i - 1][j - 1] + 1;
//                  else {
    
    
//                     a[i - 1] != b[j - 1] f[i][j] = 0;  // 初始化以默认为0
//                  }
                 if(maxlen < f[i][j]){
    
    
                     maxlen = f[i][j];
                     idx = i; // idx记录从1开始,下面idx - maxlen + 1 -1 
                 }
                 
             }
        if(maxlen == 0) return "-1";
        return a.substr(idx - maxlen,maxlen);
        
    }
};

链表求和

来存储倒序,尾插法

/**
 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 * };
 */

class Solution {
    
    
public:
    /**
     * 
     * @param head1 ListNode类 
     * @param head2 ListNode类 
     * @return ListNode类
     */
    ListNode* addInList(ListNode* head1, ListNode* head2) {
    
    
        // write code here
        stack<int> stk1,stk2;
        while(head1){
    
    
            stk1.push(head1->val);
            head1=head1->next;
        }
        while(head2){
    
    
            stk2.push(head2->val);
            head2=head2->next;
        }
        
        int sum = 0, carry = 0;
        ListNode *cur = NULL;
        while(stk1.size() || stk2.size() || carry)
        {
    
    
            sum = 0;
            if(stk1.size()){
    
    
                sum += stk1.top();
                stk1.pop();
            }
            if(stk2.size()){
    
    
                sum += stk2.top();
                stk2.pop();
            }
            sum += carry;
            carry = sum / 10;
            
            ListNode *t = new ListNode(sum % 10);
            t->next = cur;
            cur = t;
         
        }
        return cur;
    }
};

二叉树的最近公共祖先

O ( n ) O(n) O(n)

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

class Solution {
    
    
public:
    /**
     * 
     * @param root TreeNode类 
     * @param o1 int整型 
     * @param o2 int整型 
     * @return int整型
     */
    int lowestCommonAncestor(TreeNode* root, int o1, int o2) {
    
    
        // write code here
        if(root == NULL) return -1; 
        if(root->val == o1 || root->val == o2) return root->val;
        
        int left = lowestCommonAncestor(root->left,  o1,  o2);
        int right = lowestCommonAncestor(root->right,  o1,  o2);
        if(left == -1) return right;
        if(right == -1) return left;
        return root->val;
    }
};

二叉树的之字形遍历

二叉树的遍历 + 奇数行反转

/**
 * 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> > zigzagLevelOrder(TreeNode* root) {
    
    
        // write code here
        vector<vector<int> > res;
        if(!root) return res;
        
        queue<TreeNode*> q;
        q.push(root);
        while(q.size()){
    
    
            int n = q.size();
            vector<int> cur;
            while(n -- ){
    
    
                auto t = q.front();
                q.pop();
                cur.push_back(t->val);
                if(t->left) q.push(t->left);
                if(t->right) q.push(t->right);
            }
            res.push_back(cur);
        }
        for(int i = 0; i < res.size();i ++ )
            if(i % 2) reverse(res[i].begin(),res[i].end());
        
        return res;
    }
};

大数加法

字符串模拟

class Solution {
    
    
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 计算两个数之和
     * @param s string字符串 表示第一个整数
     * @param t string字符串 表示第二个整数
     * @return string字符串
     */
    string solve(string s, string t) {
    
    
        // write code here
        vector<int> a,b;
        for(int i = s.size() - 1;i >= 0;i -- ) a.push_back(s[i] - '0');
        for(int i = t.size() - 1;i >= 0;i -- ) b.push_back(t[i] - '0');
        
        auto c = add(a,b);
        string res;
        for(int i = c.size() - 1;i >= 0;i -- ) res += c[i] + '0';
        return res;
    }
    
    vector<int> add(vector<int> &a,vector<int> &b)
    {
    
    
        vector<int> res;
        int t = 0;
        for(int i = 0;i < a.size() || i < b.size();i ++ )
        {
    
    
            if(i < a.size()) t += a[i];
            if(i < b.size()) t += b[i];
            res.push_back(t % 10);
            t /= 10;
        }
        if(t) res.push_back(t);
        return res;
    }
};

反转字符串

双指针原地交换

class Solution {
    
    
public:
    /**
     * 反转字符串
     * @param str string字符串 
     * @return string字符串
     */
    string solve(string str) {
    
    
        // write code here
        for(int i = 0,j = str.size() - 1;i < j;i ++ ,j -- )
            swap(str[i],str[j]);
        return str;
    }
};

两个链表的第一个公共结点

走两边,a+b+c

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
    
    
public:
    ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
    
    
        auto p = pHead1, q = pHead2;
        while(p != q)
        {
    
    
            if(p) p = p->next;
            else p = pHead2;
            if(q) q = q->next;
            else q = pHead1;
        }
        return p;
    }
};

螺旋矩阵

方向矢量模拟

class Solution {
    
    
public:
    vector<int> spiralOrder(vector<vector<int> > &matrix) {
    
    
        if(matrix.empty() || matrix[0].empty()) return {
    
    }; // 特判!!!
        
        int n = matrix.size(), m = matrix[0].size();
        int dx[] = {
    
    -1,0,1,0}, dy[] = {
    
    0,1,0,-1}; // 四个方向矢量
        vector<vector<bool>> st(n,vector<bool>(m));
        vector<int> res;
        int x = 0,y = 0,d = 1;
        for(int i = 0;i < n * m;i ++)
        {
    
    
            res.push_back(matrix[x][y]);
            st[x][y] = true;
            int a = x + dx[d], b = y + dy[d];
            if(a < 0 || a >= n || b < 0 || b >= m || st[a][b])
            {
    
    
                d = (d + 1) % 4;
                a = x + dx[d], b = y + dy[d];
            }
            x = a, y = b;
        }
        return res;
    }
};

重建二叉树

递归构建二叉树,根据前序遍历找到根,中序遍历根左边是左子树,右边是右子树,递归处理。

#include <unordered_map>

/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
    
    
public:
    
    unordered_map<int,int> pos;
    
    TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
    
    
        int n = vin.size();
        for(int i = 0;i < n;i ++ ) pos[vin[i]] = i;
        return dfs(pre, vin,0,n - 1,0,n - 1);
    }
    
    TreeNode* dfs(vector<int> &pre,vector<int> &inorder,int pl,int pr,int il,int ir)
    {
    
    
        if(pl > pr) return NULL;
        
        int val = pre[pl];
        int k = pos[val];
        int len = k - il;
        TreeNode *root = new TreeNode(val);
        root->left = dfs(pre,inorder,pl + 1,pl + len,il,k - 1);
        root->right = dfs(pre,inorder,pl + len + 1,pr,k + 1,ir);
        return root;
    }
};

求平方根

值域二分,边界处理

class Solution {
    
    
public:
    /**
     * 
     * @param x int整型 
     * @return int整型
     */
    int sqrt(int x) {
    
    
        // write code here
        int l = 0,r = x;
        while(l < r)
        {
    
    
            int mid = (long long)l + r + 1 >> 1; // 防止溢出
            if(mid <= x / mid) l = mid; // 防止溢出
            else r = mid - 1;
        }
        return r;
    }
};

猜你喜欢

转载自blog.csdn.net/weixin_43154149/article/details/113795273
30