力扣29两数相除C++

本文探讨了一种将除法转换为减法的方法,通过改进循环策略,减少迭代次数,以提高整数除法的效率。然而,尽管减少了超时问题,但时间复杂度仍然不理想。作者寻求优化或寻找替代算法来提升代码性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

请点击

思路

  • 最主要的想法就是,除法其实就是多次减法,所以,把除法改成了减法,每减去1次,则商加1(商初始为0)。
  • 但是,这样子超时了…
  • 所以,接下来就干脆,每次循环减去两次除数,商+2
  • 剩下的都是边界值的情况,见代码

代码

#include<iostream>
#include<cmath>
using namespace std;
int divide(int dividend, int divisor) {
    int sym=1;//符号。若被除数与除数中有一个为负,则sym=-1
    long int quotient=0;//使用long int的原因在于防止计算过程中溢出
    long int divid = dividend;
    long int divi = divisor;

    if(divid == 0) return 0;//若被除数为0,则商为0
    //被除数可表示正负最大,除数为正负1时,的边界值情况
    if( (divid <= -2147483648 && divi==-1) || (divid >= 2147483647 && divi==1) ) return 2147483647;
    if( (divid <= -2147483648 && divi==1) || (divid >= 2147483647 && divi==-1) ) return -2147483648;

    if(divid<0){//将负的被除数,变成正的
        divid = -divid;
        sym = -sym;
    } 
    if(divi<0){//将负的除数,变成正的
        divi = -divi;
        sym = -sym;
    }

    while(divid >= (divi + divi)){//每次循环减去两次除数,则商每次需要+2
        divid = divid - (divi + divi);
        quotient = quotient + 2;
    }
    if(divid >= divi){//最后,可能只够减去1个除数,商+1
        divid -= divi;
        quotient += 1;
    }
    
    if(sym!=1) quotient = -quotient;
    
    return quotient;
}
int main(){
    int dividend, divisor;
    cin>>dividend>>divisor;
    long int quotient = divide(dividend, divisor);
    cout<<quotient<<endl;
    return 0;
}

but,这样子,用时直接1296ms… 还是需要再优化或者换方法

### LeetCode 'Two Sum' 问题的 C++ 解决方案 #### 暴力解法 (Brute Force Approach) 暴力方法通过双重循环遍历数组中的每一对元素,检查它们之和是否等于目标值 `target`。这种方法的时间复杂度为 \(O(n^2)\),空间复杂度为 \(O(1)\)[^1]。 ```cpp class Solution { public: vector<int> twoSum(vector<int>& nums, int target) { for(int i = 0; i < nums.size(); i++) { for(int j = i + 1; j < nums.size(); j++) { if(nums[j] == target - nums[i]) { return {i, j}; } } } return {-1, -1}; } }; ``` --- #### 哈希表优化解法 (Hash Table Optimization) 为了提高效率,可以使用哈希表存储已经访问过的数值及其索引位置。这样可以在一次遍历中完成查找操作,时间复杂度降低到 \(O(n)\),而空间复杂度增加至 \(O(n)\)[^3]。 ```cpp #include <unordered_map> using namespace std; class Solution { public: vector<int> twoSum(vector<int>& nums, int target) { unordered_map<int, int> hashTable; for(int i = 0; i < nums.size(); ++i){ int complement = target - nums[i]; if(hashTable.find(complement) != hashTable.end()){ return {hashTable[complement], i}; } hashTable[nums[i]] = i; } return {}; } }; ``` 此代码利用了一个无序映射 (`unordered_map`) 来记录已扫描的数字以及其对应的下标。每次迭代都会计算当前数字所需的补数,并检查该补数是否已经在哈希表中存在。 --- #### 排序数组上的双指针技术 (Two Pointers Technique on Sorted Array) 如果输入数组已经是有序的,则可以通过双指针的方法进一步减少内存消耗并提升性能。初始时设置左指针指向第一个元素,右指针指向最后一个元素;随后逐步调整两个指针的位置直到找到满足条件的一对数字或者确认不存在这样的组合[^2]。 ```cpp class Solution { public: vector<int> twoSum(vector<int>& numbers, int target) { int l = 0, r = numbers.size() - 1; while(l < r){ if(numbers[l] + numbers[r] > target) r--; else if(numbers[l] + numbers[r] < target) l++; else return {l+1, r+1}; } return {}; } }; ``` 注意这里返回的结果是从 1 开始计数的索引值而不是默认从零开始的标准 C++ 数组索引。 --- #### 总结 上述三种算法分别代表了不同的思路和技术应用方向: - **暴力枚举**适合理解基础逻辑但不适用于大规模数据集; - **哈希表辅助**提供了更高效的解决方案,在实际开发场景中最常用; - **双指针策略**则针对特定情况(即预排序列表)进行了特殊优化处理。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值