牛客的一道区间选数题(超时版)

如果楼主没理解错,原题是两个区间,各取一个数,求两数的和的数位和,但是超时了,暂且记录

#include <iostream>
#include<math.h>
using namespace std;
int main()
{
    int n=0;
    int a1,a2,b1,b2;
    cin>>n;
    while(n--)
    {
        cin>>a1>>a2>>b1>>b2;
        int i=a1,j=0,mad=0;
        while(i<=a2)
        {
            j=b1;
            while(j<=b2)
            {
                int x=0;
                int num=i+j;
                while(num!=0)
                {
                    x+=num%10;
                    num/=10;
                }
                mad=max(x,mad);
                j++;
            }
            i++;
        }
        cout<<mad<<'\n';
    }
    return 0;
}

网等在线判系统中,代码超时通常是由于算法效率不足(如时间复杂度过高)或存在死循环等问。针对你的链表插入代码,以下是优化后的本及常见超时原因分析: --- ### **优化后的代码(避免超时)** ```cpp #include <iostream> using namespace std; 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) {} }; int main() { int n; cin >> n; int h; cin >> h; ListNode* head = new ListNode(h); // 直接使用 head,无需 dummy for (int i = 1; i < n; i++) { // 注意循环次应为 n-1 int a, b; cin >> a >> b; ListNode* curr = new ListNode(b); // 查找插入位置(优化:从 head 开始遍历) ListNode* p = head; while (p != nullptr && p->val != a) { p = p->next; } if (p != nullptr) { // 确保找到节点 a curr->next = p->next; p->next = curr; } else { // 处理未找到节点 a 的情况(根据目要求决定是否跳过或报错) delete curr; // 避免内存泄漏 } } // 输出链表 for (ListNode* p = head; p != nullptr; p = p->next) { cout << p->val << " "; } // 释放内存(判系统可能不需要,但建议保留) ListNode* p = head; while (p != nullptr) { ListNode* temp = p; p = p->next; delete temp; } return 0; } ``` --- ### **常见超时原因及解决方案** 1. **循环次错误** - 原代码中 `for (int i = 0; i < n - 1; i++)` 可能导致少插入一次节点(因为 `i` 从 0 开始)。 - **修正**:改为 `for (int i = 1; i < n; i++)`,确保插入 `n-1` 次。 2. **未处理查找失败的情况** - 如果输入的 `a` 不在链表中,原代码会直接插入 `curr->next = p->next`(此时 `p->next` 可能为 `nullptr`),但逻辑上可能不符合目要求。 - **修正**:添加 `if (p != nullptr)` 判断,避免无效插入。 3. **内存泄漏导致判系统卡死** - 未释放的动态内存可能被判系统检测为异常,间接导致超时。 - **修正**:在程序结束前释放所有 `new` 分配的内存。 4. **输入据规模过大** - 如果 `n` 很大(如 1e5),原代码的 `O(n^2)` 查找效率会超时。 - **优化**:改用哈希表(如 `unordered_map`)记录节点地址,将查找时间降为 `O(1)`。但需注意目是否允许额外空间。 --- ### **进一步优化(哈希表加速查找)** ```cpp #include <iostream> #include <unordered_map> using namespace std; struct ListNode { int val; ListNode* next; ListNode(int x) : val(x), next(nullptr) {} }; int main() { int n; cin >> n; int h; cin >> h; ListNode* head = new ListNode(h); unordered_map<int, ListNode*> nodeMap; // 记录 val -> 节点指针 nodeMap[h] = head; for (int i = 1; i < n; i++) { int a, b; cin >> a >> b; ListNode* curr = new ListNode(b); // 通过哈希表快速查找节点 a if (nodeMap.count(a)) { ListNode* p = nodeMap[a]; curr->next = p->next; p->next = curr; nodeMap[b] = curr; // 更新哈希表 } else { delete curr; // 未找到 a,释放 curr } } // 输出链表 for (ListNode* p = head; p != nullptr; p = p->next) { cout << p->val << " "; } // 释放内存 ListNode* p = head; while (p != nullptr) { ListNode* temp = p; p = p->next; delete temp; } return 0; } ``` --- ### **关键总结** 1. **时间复杂度**:原代码为 `O(n^2)`,优化后为 `O(n)`(哈希表本)。 2. **边界条件**:必须处理 `a` 不在链表中的情况。 3. **内存管理**:避免泄漏,判系统可能对内存异常敏感。 4. **输入规模**:如果 `n` 很大(如 1e5),必须优化查找逻辑。 如果仍超时,可能是目有其他隐藏条件(如链表必须保持某种顺序),建议检查目描述或示例。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值