LeetCode Easy级别 数组(一)

1.两数之和

仔细审题,题目给出的测试用例不包含全部情况,如负数加法。暴力匹配即可实现。

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        vector<int> answer;
        int record;
        for(int i=0;i!=nums.size();i++)
        {
            record = target - nums[i];     
            for(int j=i+1;j!=nums.size();j++)
                if(record == nums[j])
                {
                    answer.push_back(i);
                    answer.push_back(j);
                    break;
                }
        }
        return answer;
    }
};

26.删除排序数组中的重复项

暴力使用循环固然可以解决问题,但不能养成拿到题目就嵌套循环的习惯。在做题中要多思考循环的设置是否必要、是否可以被取代、是否可以不用。对比此题官解采用的快慢指针思想,我所写的代码第一层循环其实完全是多余的,可以被一个自增参数替代还降低了运算复杂度。这是一种需要时间积累的能力,急不得!

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        if(nums.size()==0) return 0;
        if(nums.size()==1) return 1;
        
        int i,j,temp,t=0;
        int MAX = nums[nums.size()-1];
        for(i=0;i!=nums.size()-1;i++)
        {
            for(j=i+1;j!=nums.size();j++)
            {
                if(nums[j]>nums[i])
                {
                    t++;
                    if(j!=t)
                    {
                        temp=nums[t];
                        nums[t]=nums[j];
                        nums[j]=temp;
                    }
                    break;
                }
            }
            if(nums[i+1]==MAX) break;
        }
        return t+1;
    }
};

27.移除元素

思路和T26是相似的,官解提供了两种解法:第一种类似T26,第二种利用了“其余元素可以乱序”的要求,将目标与队尾元素交换并释放,进一步优化了算法。评论中提到采用逆序循环,删除元素不存在元素移位问题。

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int i=0, j, temp;
        int len=nums.size();
        for(j=i;j!=len;j++)
        {
            if(nums[j]==val)
            {
                nums[j]=nums[i];
                nums[i]=val;
                i++;
            }
        }
        for(j=0;j<len/2;j++)
        {
            temp=nums[j];
            nums[j]=nums[len-1-j];
            nums[len-1-j]=temp;
        }
        return len-i;
    }
};

35.搜索插入位置

给定排序数组和目标值,单纯比较大小,推荐使用“二分法”思想。先与序列中值比较,再根据大小关系确定左区域 or 右区域,最后逼近结果。

class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
        int i,j;
        for(i=0;i!=nums.size();i++)
        {
            if(nums[i]==target) break;
            else{
                    if(i==0&&nums[i]>target) break;
                    else if((i==nums.size()-1)&&nums[i]<target) {i++;break;}
                    else
                        if(nums[i]<target&&nums[i+1]>target) {i++;break;}
            }    
        }
        
        return i;
    }
};

53.最大子序和

这道居然是简单题,唉 菜是原罪~ 此题思路是动态规划法或者是寻找规律,我还没弄懂,暂记录如下。

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int sum = nums[0];
        int res = nums[0];
        for (int i = 1; i < nums.size(); i++) {
            if (sum > 0) {
                sum += nums[i];
            } else {
                sum = nums[i];
            }
            if (sum > res) {
                res = sum;
            }
        }
        return res;
    }
};

66.加一

具体技巧不是很多,主要是考虑到 9+1 的进位处理,还有对规律的统划能力,我这版代码在这一方面做的就不好。

class Solution {
public:
    vector<int> plusOne(vector<int>& digits) {
        int i;
        int len = digits.size();
        if (len == 1 && digits[0] != 9)
            digits[0] += 1;
        if (len == 1 && digits[0] == 9)
        {
            digits[0] = 1;
            digits.push_back(0);
        }
            
        for(i = len-1; i > 0; i--)
        {
            if(digits[i] != 9){
                digits[i] += 1;
                break;
            }
            else{
                digits[i] = 0;
                if((digits[i-1] + 1)/10 != 1){
                    digits[i-1] += 1;
                    break;
                }if(i == 1){
                    digits[0] = 1;
                    digits.push_back(0);
                }
            }
        }
        
        return digits;
    }
};

88.合并两个有序数组

先合并成一个数组,再使用选择排序。

class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        int i=0, j=0, temp;
        for(i;i<n;i++) nums1[m+i] = nums2[i];
        
        for (i = 0; i < m + n -1 ; i++) {
            for (j = i + 1; j < m + n; j++) {
                if(nums1[i] > nums1[j]){
                    temp =  nums1[i];
                    nums1[i] = nums1[j];
                    nums1[j] = temp;
                }
            }
        }
    }
};

118.杨辉三角

找规律,没啥好说的。还可以考虑对称性质,一次计算两次赋值。

class Solution {
public:
    vector<vector<int>> generate(int numRows) {
        vector<vector<int> > W={{1},{1,1}};
        vector<int> N;
        int i, j=2;
        
        if(numRows == 0) {W.clear(); return W;}
        if(numRows == 1) {W.pop_back(); return W;}
        if(numRows == 2) return W;
        while(j!=numRows)
        {
            N.push_back(1);
            for(i=1;i<j;i++)
                N.push_back(W[j-1][i-1]+W[j-1][i]);
            N.push_back(1);
            W.push_back(N);
            N.clear();
            j++;
        }
        return W;
    }
};

119.杨辉三角II

依照118代码稍微改动即可实现。

class Solution {
public:
    vector<int> getRow(int rowIndex) {
        vector<vector<int> > W={{1},{1,1}};
        vector<int> N;
        int i, j=2;
        
        if(rowIndex == 0) return W[0];
        if(rowIndex == 1) return W[1];
        while(j!=rowIndex+1)
        {
            N.push_back(1);
            for(i=1;i<j;i++)
                N.push_back(W[j-1][i-1]+W[j-1][i]);
            N.push_back(1);
            W.push_back(N);
            N.clear();
            j++;
        }
        return W[rowIndex];
    }
};

121.买卖股票的最佳时机

 

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int i, j, pro, MAX=0;
        
        for(i=0;i<prices.size();i++)
        {
            for(j=i;j<prices.size();j++)
            {
                if(prices[i]<prices[j])
                {
                    pro = prices[j] - prices[i];
                    if(pro > MAX) MAX = pro;
                }
            }
        }
        return MAX;
    }
};

 

题目描述:给定一个非负整数数组nums和一个整数m,你需要将这个数组分成m个非空的连续子数组。设计一个算法使得这m个子数组中的最大和最小。 解题思路: 这是一个典型的二分搜索题目,可以使用二分查找来解决。 1. 首先确定二分的左右边界。左边界为数组中最大的值,右边界为数组中所有元素之和。 2. 在二分搜索的过程中,计算出分割数组的组数count,需要使用当前的中间值来进行判断。若当前的中间值不够分割成m个子数组,则说明mid值偏小,将左边界更新为mid+1;否则,说明mid值偏大,将右边界更新为mid。 3. 当左边界小于等于右边界时,循环终止,此时的左边界即为所求的结果。 具体步骤: 1. 遍历数组,找到数组中的最大值,并计算数组的总和。 2. 利用二分查找搜索左右边界,从左边界到右边界中间的值为mid。 3. 判断当前的mid值是否满足题目要求,若满足则更新右边界为mid-1; 4. 否则,更新左边界为mid+1。 5. 当左边界大于右边界时,循环终止,返回左边界即为所求的结果。 代码实现: ```python class Solution: def splitArray(self, nums: List[int], m: int) -> int: left = max(nums) right = sum(nums) while left <= right: mid = (left + right) // 2 count = 1 total = 0 for num in nums: total += num if total > mid: total = num count += 1 if count > m: left = mid + 1 else: right = mid - 1 return left ``` 时间复杂度分析:二分搜索的时间复杂度为O(logN),其中N为数组的总和,而遍历数组的时间复杂度为O(N),因此总的时间复杂度为O(NlogN)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值