米哈游笔试经验

5 篇文章 0 订阅

很可爱的一个公司,从题里面都可以看出来。

先是10道多选题,都是在应该都是在网上可以查到的那种,把牛客都做一遍就行。

然后是两道编程,一看就是leedcode上的问题,难度适中,需要想一下才知道答案。

1.leetcode 1249 - 移除无效的括号

比较简单

在此提供两种解题思路

First:

string minRemoveToMakeValid(string s) {
    stack <int> _stack;
    vector <int> deleteVector;
    for (int i = 0; i < s.size (); i++) {
        if (s[i] == '(') {
            _stack.push (i);
        } else if (s[i] == ')') {
            if (!_stack.empty ()) {
                _stack.pop ();
            } else {
                deleteVector.push_back (i);
            }
        }
    }
    // 此时栈中的元素和deleteVector中的元素是需要删除的元素
    // 还要注意的是删除的时候要从后面往前面删除,不然i所指向的位置就不对了
    while (!_stack.empty () || !deleteVector.empty ()) {
        if (_stack.empty ()) {
            while (!deleteVector.empty ()) {
                s.erase (deleteVector.back (), 1);
                deleteVector.pop_back ();
            }
        } else if (deleteVector.empty ()) {
                s.erase (_stack.top (), 1);
                _stack.pop ();
        } else {
                s.erase (_stack.top () > deleteVector.back () ? _stack.top () : deleteVector.back (), 1);
                if (_stack.top () > deleteVector.back ()) {
                    _stack.pop ();
                } else {
                    deleteVector.pop_back ();
                }
        }
    }
    return s;
}

Second:

string minRemoveToMakeValid1(string s) {
    // 上个算法是左右括号分开计算的,这次要写二者合二为一的算法
    vector<int> deleteStack;
    for (int i = 0; i < s.size (); i++) {
        if (s [i] == '(') {
            deleteStack.push_back (i);
        } else if (s [i] == ')') {
            // 对于右括号找第一个配对的左括号删除,没有则压栈,栈为空也压栈
            if (!deleteStack.empty ()) {
                bool flag = true;
                // 此处应该用迭代器,而不是数组访问方式
                /*
                for (int j = deleteStack.size () - 1; j >= 0; j--) {
                    if (deleteStack [j] == '(') {
                        // 忽略这个右括号,并且从删除栈中删除左括号
                        deleteStack.erase (j);
                        flag = true;
                        break;
                    }
                }
                /**/

                for (vector<int>::iterator item = deleteStack.end () - 1; item >= deleteStack.begin (); item--) {
                    if (s[(*item)] == '(') {
                        deleteStack.erase (item);
                        flag = false;
                        break;
                    }
                }
                // 这个右括号需要删除
                if (flag) deleteStack.push_back (i);
            } else {
                deleteStack.push_back (i);
            }
        }
    }

    // 此时只需要删除栈中元素即可
    while (!deleteStack.empty ()) {
        s.erase (deleteStack.back (), 1);
        deleteStack.pop_back ();
    }
    return s;
}

2.leetcode 1035 - 不相交的线

int longestCommonSubsequence(string text1, string text2) {
    int dp[100][100];
    for (int i = 0; i < text1.length (); i++) {
        for (int j = 0; j < text2.length (); j++) {
            if (text1 [i] == text2 [j]) {
                // 相等则左上角加
                if (i == 0 || j == 0) {
                    dp [i][j] = 1;
                } else {
                    dp [i][j] = dp [i - 1][j - 1] + 1;
                }
            } else {
                if (i == 0 || j == 0) {
                    if (i == 0 && j == 0) {
                        dp [i][j] = 0;
                    } else if (i == 0) {
                        dp [i][j] = dp [i][j - 1] > 0 ? dp [i][j - 1] : 0;
                    } else if (j == 0) {
                        dp [i][j] = dp [i - 1][j] > 0 ? dp [i - 1][j] : 0;
                    }
                } else {
                    dp [i][j] = dp [i - 1][j] > dp [i][j - 1] ? dp [i - 1][j] : dp [i][j - 1];
                }
            }
        }
    }
    return dp [text1.length () - 1][text2.length () - 1];
}

这道题还是挺有意思的,本来是一个无从下手的问题,但是可以把问题转换成找最长公共子序列却非常的简单。其实只有所有的线不相交才能是最长子序列,二者其实是互补的。所以只需要动态规划建一张动态表就可以实现。最后返回表的最后一个选项即可。

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值