建信金科笔试编程题

1、给一个字符串,只包含字母和空格,其中由连续的字母组成的是单词,问你字符串中有几个连续的三个单词满足:第一个单词=第二个单词,且不等于第三个单词。

解题思路:先做字符串分割,然后把分割出来的单词放入列表(C++中的或者Java中的),然后就是简单的枚举判断,符合条件计数器+1.

2、给定一个链表,要求把不存在相邻元素相等的连续段进行反转操作,返回操作后的链表。

解题思路:我的做法是先把链表转成列表,方便访问相邻元素,然后枚举元素,若存在相邻元素与之相等,那么就直接将该元素尾插到新链表中,否则就先存放到列表中,直到出现存在相邻元素与之相等的元素,再将反转后的列表尾插到新链表中。

由于采用的是枚举,就算加上反转操作,时间复杂度也还是线性的。

考试代码参考:

#include <bits/stdc++.h>
#define pb push_back
using namespace std;
struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(nullptr) {}
};
class Solution {
public:
    ListNode *convert_to_list(vector<int>&a) {
        ListNode *head = new ListNode(-1);
        head->next = NULL;
        ListNode *p = head;
        for(int i = 0; i < a.size(); i++) {
            ListNode *q = new ListNode(a[i]);
            p->next = q;
            p = q;
        }
        p->next = NULL;
        return head->next;
    }
    void output(ListNode *head) {
        ListNode *p = head;
        while(p) {
            cout << p->val << " ";
            p = p->next;
        }
    }
    ListNode *solve(ListNode *head) {
        if(head == NULL)    return NULL;
        vector<int>a, v;
        ListNode *p = head;
        while(p) {
            a.pb(p->val);
            p = p->next;
        }
        ListNode *L = new ListNode(-1);
        L->next = L;
        p = L;
        for(int i = 0; i < a.size(); i++) {
            if(i == 0) {
                if(a[i] == a[i + 1]) {
                    ListNode *q = new ListNode(a[i]);
                    p->next = q;
                    p = q;
                }
                else {
                    v.pb(a[i]);
                }
                continue;
            }
            if(i == a.size() - 1) {
                if(a[i] == a[i - 1]) {
                    ListNode *q = new ListNode(a[i]);
                    p->next = q;
                    p = q;
                }
                else {
                    v.pb(a[i]);
                }
                continue;
            }
            if(a[i] == a[i - 1] || a[i] == a[i + 1]) {
                reverse(v.begin(), v.end());
                for(auto val : v) {
                    ListNode *q = new ListNode(val);
                    p->next = q;
                    p = q;
                }
                v.clear();
                ListNode *q = new ListNode(a[i]);
                p->next = q;
                p = q;
            }
            else {
                v.pb(a[i]);
            }
        }
        if(v.size()) {
            reverse(v.begin(), v.end());
            for(auto val : v) {
                ListNode *q = new ListNode(val);
                p->next = q;
                p = q;
            }
        }
        p->next = NULL;
        return L->next;
    }
};
int main() {
    int n;
    cin >> n;
    vector<int>a(n);
    for(int i = 0; i < n; i++)    cin >> a[i];
    Solution sol = Solution();
    ListNode *list = sol.convert_to_list(a);
    ListNode *res = sol.solve(list);
    sol.output(res);
}
/*
input:
11
1 2 2 3 4 5 3 3 3 4 5
output:
1 2 2 5 4 3 3 3 3 5 4
*/

通过率:100%

当然考虑代码量的话,也可以先操作列表,再由列表转链表。与此同时,代码可读性可能就差点了。

参考代码:

#include <bits/stdc++.h>
#define pb push_back
using namespace std;
struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(nullptr) {}
};
class Solution {
public:
    ListNode *convert_to_list(vector<int>&a) {
        ListNode *head = new ListNode(-1);
        head->next = NULL;
        ListNode *p = head;
        for(int i = 0; i < a.size(); i++) {
            ListNode *q = new ListNode(a[i]);
            p->next = q;
            p = q;
        }
        p->next = NULL;
        return head->next;
    }
    void output(ListNode *head) {
        ListNode *p = head;
        while(p) {
            cout << p->val << " ";
            p = p->next;
        }
    }
    ListNode *solve(ListNode *head) {
        if(head == NULL)    return NULL;
        vector<int>a;
        ListNode *p = head;
        while(p) {
            a.pb(p->val);
            p = p->next;
        }
        int l = 0;
        bool f = false;//是否位于不存在相邻元素相等的连续段 
        for(int i = 1; i < a.size(); i++) {
            if(i == a.size() - 1) {
                if(a[i] != a[i - 1]) {
                    reverse(a.begin() + l, a.end());
                }
                continue;
            }
            if(a[i] == a[i - 1] || a[i] == a[i + 1]) {
                if(f) {
                    reverse(a.begin() + l, a.begin() + i);
                }
                f = false;
            }
            else {
                if(!f) {
                    l = i;//记录一下开始出现相邻元素不相等的元素的位置 
                    f = true;
                }    
            }
        }
        ListNode *L = convert_to_list(a);
        return L;
    }
};
int main() {
    int n;
    cin >> n;
    vector<int>a(n);
    for(int i = 0; i < n; i++)    cin >> a[i];
    Solution sol = Solution();
    ListNode *list = sol.convert_to_list(a);
    ListNode *res = sol.solve(list);
    sol.output(res);
}
/*
input:
11
1 2 2 3 4 5 3 3 3 4 5
output:
1 2 2 5 4 3 3 3 3 5 4
*/
#校招##建信金科##秋招#
全部评论
第一题的用例让我怀疑这公司够不够正经😏
4 回复 分享
发布于 2022-10-30 22:52 上海
第二题除了python什么都可以用,直接g
2 回复 分享
发布于 2022-10-29 21:57 重庆
大佬写的是对的  没有bug
1 回复 分享
发布于 2022-10-29 21:55 湖北
哭了,java只能reverse整个数组,当时想过又觉得新开辟数组很麻烦。 另外有一个疑惑想问一下,就是reverse的a.begin()+i那里,C++的是end是闭区间的吗,是就没问题。不是的话,不应该在i指向第二个3(5后面那个3)的时候进行反转吗,这样就多翻转了一个? 求指教谢谢答主
1 回复 分享
发布于 2022-10-30 20:26 天津
好牛
点赞 回复 分享
发布于 2022-10-30 11:44 上海
友友,你是啥时候申请的,你的申请状态是笔试吗
点赞 回复 分享
发布于 2022-10-31 20:12 广东

相关推荐

16 65 评论
分享
牛客网
牛客企业服务