(一)小白入门leetCode之array 简单题目 C++实现

刷题入门题目总结一下

27 移除链表元素

解法一
指向同一个向量/数组的两个指针,一个表示结果的数组尾巴:p,另一个循环遍历整个数组:q。在这个过程种,如果q遇到了不合适的值就直接跳过,如果遇到了合适的值,就把他添加到p的后面。
注意特殊的情况,数组为空或者1等;
双指针法进行了许多复制操作。

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        if(nums.size()==0)return nums.size();
        int a=0;
        for(int j=0;j<nums.size();j++){
            if(nums[j]!=val)nums[a++]=nums[j];           
        }
        return a;
        

    }
};

解法二
为了减少不必要的复制,也就是说如果这个值不是要剔除的,就不动他,所以把重复的值删掉就可以。或者移到最后面,数组大小减一。

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        
        for(int j=0;j<nums.size();){
            if(nums[j]==val)nums.erase(nums.begin()+j);       
            else j++;    
        }
        return nums.size();     
    }
};

35 搜索插入的位置

题目:给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。你可以假设数组中无重复元素。

方法一:
用find函数来查找,如果找到了返回索引,找不到就插入;插入后,进行排序,然后再查找、返回索引。
这种方法非常朴素,时间和空间效率都很低。

#include<algorithm>

class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
        vector<int>::iterator it;
        it=find(nums.begin(),nums.end(),target);
        if(it!=nums.end())return it-nums.begin();
        nums.push_back(target);
        sort(nums.begin(),nums.end());
        return find(nums.begin(),nums.end(),target)-nums.begin();


    }
};

方法二:
其实这个题是寻找target合适的位置,只要找到大于等于他的位置,要么是他的位置,要么是他将要插入的位置。

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

方法三:
二分查找,时间复杂度O(n)变为O(logn)。这道题想要考察的应该就是二分查找。
二分查找的思想就是先取一个中间的数,进行比较,然后缩小区间,等。如果没找到,left就是刚好比target大一点的索引;

class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
    int left=0, right=nums.size()-1, mid;
    while (left <= right) {
        mid = (left + right) / 2;
        if (target == nums[mid])return mid;
        else if (target < nums[mid])right = mid - 1;
        else left = mid + 1;
    }
    return left; 
    }
};

53. 最大子序和

这道题有些难度。

方法一:动态规划

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int sum=0;
         int a;
         int ans=nums[0];
        for(int i=0;i<nums.size();i++){
            a=nums[i];
            if(sum>0)sum+=a;
            else sum=a;
            ans=ans>sum?ans:sum;     //这一行很重要,加上这个才能得到全局最优
        }
        return ans;
    }
};

暴力、贪心、分治 等方法还有很多,有必要都看一看。

66. 加一

给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一。 最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。
你可以假设除了整数 0 之外,这个整数不会以零开头。

解法一:
首先要取到数组的最后一位数,相加后的和即为sum. Sum的余数放在这一位,sun/10应该和前一位相加,直到为0的时候停止。
但是要考虑到,第一个数只加一,后面的数只加产生的进位,和第一个数也有进位这种情况。

class Solution {
public:
    vector<int> plusOne(vector<int>& digits) {
        int sum=0;
        int i=digits.size()-1;
        digits[i]+=1;
        while(i>=0){            
            sum+=digits[i];
            digits[i]=sum%10;
            if(sum/10==0)return digits;
            else {
                i--;  
                sum/=10;
            }          
        }
        if(i<0) digits.insert(digits.begin(), sum);
        return digits;
    }
};

解法二:递归?
本题中最后一个数只加一,产生的进位最大也只是1;所以,递归的跳出条件是,传入的数组末尾加一无进位,就返回这个数组。或者已经到达了数组的开头,就插入然后返回数组。

class Solution {
public:
    vector<int> plusOne(vector<int>& digits) {        
        int i=digits.size()-1;
        return F(digits, i);        
    }
    vector<int> F(vector<int>& digits, int i) {
        if(digits[i]+1>9){
            digits[i]=(digits[i]+1)%10;
            if(i==0){
                digits.insert(digits.begin(), 1);
                return digits;
            }
            else return F(digits, i-1);
        }
        else{
            digits[i]=(digits[i]+1);
            return digits;
        }
    }    
};

方法三:
如果是9这一位置为0,否则返回本位加1后的数组。

class Solution {
public:
    vector<int> plusOne(vector<int>& digits) {        
        for(int i=digits.size()-1;i>=0;i--){
            if(digits[i]==9)digits[i]=0;
            else {
                digits[i]++;
                return digits;
            }
        }
        digits.insert(digits.begin(),1);
        return digits;        
    }    
};

88. 合并两个有序数组

给你两个有序整数数组 nums1 和 nums2,请你将 nums2 合并到 nums1 中,使 num1 成为一个有序数组。

解法一:
有些麻烦的解法,就是比较开头的两个大小,插入,数组2指针右移。不插入,数组1指针右移。

class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        int i=0, j=0;
        while(j<n){
            if(i>=m)while(j<n)nums1[i++]=nums2[j++];
            else if(nums1[i]<=nums2[j])i++;
            else {
                nums1.insert(nums1.begin()+i,nums2[j]);
                nums1.pop_back();
                m++;
                j++;
            }
        }

    }
};

方法二:
假装有第三个数组,每次在数组1、2中选择一个小的复制进来。但是为了节约空间,不复制num1,就从num1的尾巴开始。

class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        int p1=m-1,p2=n-1,q=m+n-1;
        while(p1>=0&&p2>=0)            
            nums1[q--]=nums1[p1]>nums2[p2]?nums1[p1--]:nums2[p2--];
        while(p2>=0)nums1[q--]=nums2[p2--];
    }
};

方法三:
把数组2替换掉数组1里的0,然后.sort()排序。这样就不能利用数组有序这一点。

class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        nums1.insert(nums1.begin()+m, nums2.begin(),nums2.end());
        nums1.resize(m+n);
// copy(nums2.begin(),nums2.end(),nums1.begin() + m);
        sort(nums1.begin(),nums1.end());
    }
};

118. 杨辉三角

解法一:
先把向量的每一行初始化为1,每一行的列数都和第几行相等,由此可以进行初始化;
然后从第二列开始,用上一行的两个数相加计算。嵌套两个for循环可以完成。

class Solution {
public:
    vector<vector<int>> generate(int numRows) {
        vector<vector<int>> re(numRows);         
            for(int i=0;i<numRows;i++){
                re[i].resize(i+1,1);
                for(int j=1;j<i;j++)
                    re[i][j]=re[i-1][j-1]+re[i-1][j];                
            }
        return re;
    }
};

如果不先把每一行初始化成1,可以增加一个判断,第一列和最后一列re[i].push_back(1)

数组部分的题目就先到这里结束了,下一篇文章是关于字符串的简单题目

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值