这里记录了LeetCode初级算法中数组的一些题目:

加一

本来想先转成整数,加1后再转回去;耽美想到测试的例子考虑到了这个方法的笨重,所以int类型超了最大范围65536,导致程序出错。

  1. class Solution {
  2. public:
  3. vector<int> plusOne(vector<int>& digits) {
  4. int m=digits.size();
  5. int old=0;
  6. for(int i=0;i<m;i++)
  7. {
  8. old=old*10+digits[i];
  9. }
  10. int re=old+1;
  11. vector<int> a;
  12. while(re!=0)
  13. {
  14. a.insert(a.begin(),re%10);
  15. re=re/10;
  16. }
  17. return a;
  18. }
  19. };

下面完全是从数组的角度进行的思考:分析了各种情况综合得出代码:

  1. class Solution {
  2. public:
  3. vector<int> plusOne(vector<int>& digits) {
  4. int m=digits.size();
  5. if(m==1&&digits[0]==0) {digits[0]+=1;return digits;}
  6. for(int i=m-1;i>=0;i--)
  7. {
  8. if(digits[i]==9) digits[i]=0;
  9. else {digits[i]+=1;return digits;}
  10. }
  11. if(digits.front()==0) digits.insert(digits.begin(),1);
  12. return digits;
  13. }
  14. };

此外还有一种解法:

这种方法就很机智的将进位carry这个思路加了进来,如果carry=0的话就说明暂时没有进位,可以直接返回;如果有进位的话继续操作。最后在循环结束后,如果还有进位,说明要加1,用和前一个解法的insert就可以了。

  1. class Solution {
  2. public:
  3. vector<int> plusOne(vector<int>& digits) {
  4. if (digits.empty()) return digits;
  5. int carry = 1, n = digits.size();
  6. for (int i = n - 1; i >= 0; --i) {
  7. if (carry == 0) return digits;
  8. int sum = digits[i] + carry;
  9. digits[i] = sum % 10;
  10. carry = sum / 10;
  11. }
  12. if (carry == 1) digits.insert(digits.begin(), 1);
  13. return digits;
  14. }
  15. };

从排序数组中删除重复项

下面是我最初始的想法,通过循环,遍历的这一项等于前一项的话,就通过迭代器iterator it将这一项清除掉,如果不相等就将count加1;这样觉得很完美,但是实际上每次将这一项清除掉的时候,vector的总长度就发生变化了,所以会导致出错!!!下面是错误代码:

  1. class Solution {
  2. public:
  3. int removeDuplicates(vector<int>& nums) {
  4. int count=1;
  5. if(nums.size()==0) return 0;
  6. if(nums.size()==1) return 1;
  7. for(int i=1;i<nums.size();i++)
  8. {
  9. if(nums[i]==nums[i-1])
  10. {
  11. std::vector<int>::iterator it=nums.begin()+i-1;
  12. nums.erase(it);
  13. }
  14. else count++;
  15. }
  16. return count;
  17. }
  18. };

更换思路,发现题目中有这样的一句话:不需要理会新的数组长度后面的元素;这叫告诉我们,可以把不需要的元素弄到后面去或者将我们需要的元素弄到前面来,所以有了下面的解法:

  1. class Solution {
  2. public:
  3. int removeDuplicates(vector<int>& nums) {
  4. int m=nums.size();
  5. if(m==0) return 0;
  6. if(m==1) return 1;
  7. int count=0;
  8. for(int i=1;i<m;i++)
  9. {
  10. if(nums[i]!=nums[count])
  11. nums[++count]=nums[i];
  12. }
  13. return count+1;
  14. }
  15. };

只出现一次的数字

  1. #include <algorithm>
  2. using namespace std;
  3. class Solution {
  4. public:
  5. int singleNumber(vector<int>& nums) {
  6. if(nums.size()==0) return 0;
  7. if(nums.size()==1) return nums[0];
  8. int m=nums.size();
  9. sort(nums.begin(),nums.end());
  10. for(int i=1;i<nums.size();i=i+2)
  11. {
  12. if(nums[i]!=nums[i-1]) return nums[i-1];
  13. }
  14. return nums[m-1];
  15. }
  16. // private:
  17. // bool compare(int a,int b)
  18. // {
  19. // return a<b;
  20. // }
  21. };

移动零

典型的双指针的应用!!

  1. class Solution {
  2. public:
  3. void moveZeroes(vector<int>& nums) {
  4. int fast=0,slow=0;
  5. int m=nums.size();
  6. while(fast<m)
  7. {
  8. if(nums[fast]!=0)
  9. {
  10. nums[slow]=nums[fast];
  11. slow++;
  12. }
  13. fast++;
  14. }
  15. for(int i=slow;i<m;i++)
  16. nums[i]=0;
  17. }
  18. };

两个数组的交集

首先就想到两个for循环,然后在新创建的vector中进行排序、去重,输出即可:

  1. class Solution {
  2. public:
  3. vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
  4. //sort(nums1.begin(),nums1.end());
  5. //sort(nums2.begin(),nums2.end());
  6. vector<int> c;
  7. if(nums1.size()==0||nums2.size()==0) return c;
  8. for(int i=0;i<nums1.size();i++)
  9. {
  10. for(int j=0;j<nums2.size();j++)
  11. {
  12. if(nums1[i]==nums2[j])
  13. c.push_back(nums1[i]);
  14. }
  15. }
  16. sort(c.begin(), c.end());
  17. vector<int>::iterator iter = unique(c.begin(), c.end());
  18. c.erase(iter, c.end());
  19. return c;
  20. }
  21. };

这里说一下如何对vector进行去重,想到的方法有两个:利用set或者unique(),其中unique()函数是这样的,

  1. sort (a, a + n);
  2. vector<int>v (a, a + n);
  3. vector<int>::iterator it = unique(v.begin(), v.end() );
  4. v.erase (it, v.end() );//这里就是把后面藏起来的重复元素删除了

而set则更为简单,设置一个set,再将vector的数据重新传入set中,时间复杂度较小而且较方便。

然后,看了看大神的代码,他直接用了set的取集合交集set_intersection,代码如下:

  1. class Solution {
  2. public:
  3. vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
  4. set<int> s1(nums1.begin(),nums1.end()),s2(nums2.begin(),nums2.end()),res;
  5. set_intersection(s1.begin(),s1.end(),s2.begin(),s2.end(),inserter(res,res.begin()));
  6. return vector<int>(res.begin(),res.end());
  7. }
  8. };

更多关于set的用法可以参看这一篇博客

两个数组的交集2

  1. class Solution {
  2. public:
  3. vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
  4. vector<int> c;
  5. if(nums1.size()==0||nums2.size()==0) return c;
  6. sort(nums1.begin(),nums1.end());
  7. sort(nums2.begin(),nums2.end());
  8. int i=0,j=0;
  9. while(i<nums1.size()&&j<nums2.size())
  10. {
  11. if(nums1[i]==nums2[j])
  12. {
  13. c.push_back(nums1[i]);
  14. i++;j++;
  15. }
  16. else if(nums1[i]>nums2[j])
  17. j++;
  18. else
  19. i++;
  20. }
  21. return c;
  22. }
  23. };

ValidSudoku

这道题真的挺有意思,但因为不用判断数独是否有解,所以降低了很多难度。基本思路是这样的,针对每一行每一列判断是否有重复的数字,然后在针对每个九宫格进行判断。而判断是否重复的方法挺巧妙的,就是利用数组小表的唯一性。a[nums]初始值为0,出现过一次数字后变为1,nums是由所填数字的下表来决定的,举个例子就会清楚了:假如第一行里有两个7,nums[7】初始值为0,在第一次7的时候nums[7]变为了1,在第二次遇到7的时候由于之前已经变为了7,简单的判断语句就能发现这里实际上出现了问题。下面贴上代码:

  1. class Solution {
  2. public:
  3. bool isValidSudoku(vector<vector<char>>& board) {
  4. int i,j,k,l,map[10];
  5. if(board.size()!=9 || board[0].size()!=9)return false;
  6. for(i=0;i<9;i++){
  7. memset(map,0,sizeof(map));
  8. for(j=0;j<9;j++){
  9. if(board[i][j]=='.')continue;
  10. if(board[i][j]<'0' || board[i][j]>'9')return false;
  11. int num=board[i][j]-'0';
  12. if(map[num])return false;
  13. map[num]=1;
  14. }
  15. }
  16. for(j=0;j<9;j++){
  17. memset(map,0,sizeof(map));
  18. for(i=0;i<9;i++){
  19. if(board[i][j]=='.')continue;
  20. int num=board[i][j]-'0';
  21. if(map[num])return false;
  22. map[num]=1;
  23. }
  24. }
  25. for(i=0;i<9;i+=3){
  26. for(j=0;j<9;j+=3){
  27. memset(map,0,sizeof(map));
  28. for(k=i;k<i+3;k++){
  29. for(l=j;l<j+3;l++){
  30. if(board[k][l]=='.')continue;
  31. int num=board[k][l]-'0';
  32. if(map[num])return false;
  33. map[num]=1;
  34. }
  35. }
  36. }
  37. }
  38. return true;
  39. }
  40. };

旋转图像

这道题我感觉比较奇怪,思路比较好像用的是reverse与swap,我看了别人的代码只是先后顺序不同而已,但是自己的代码(注释掉的)却在输入为44矩阵时不能执行reverse,而自己在私下测试了reverse确实是可以将44矩阵执行reverse操作的,自己的想法是先将行数倒置,然后沿着主对角线进行swap()操作,得到最终结果。而我最终的代码,是先交换在倒置,我认为先后顺序是没有问题的,但是程序却没有执行reverse的操作,就很奇怪。

  1. class Solution {
  2. public:
  3. void rotate(vector<vector<int>>& matrix) {
  4. /*
  5. for(int i=0;i<matrix.size();i++)
  6. reverse(matrix.begin(),matrix.end());
  7. for(int i=0;i<matrix[0].size();i++)
  8. {
  9. for(int j=i+1;j<matrix.size();j++)
  10. {
  11. swap(matrix[i][j],matrix[j][i]) ;
  12. }
  13. }*/
  14. int n = matrix.size();
  15. for (int i = 0; i < n; ++i) {
  16. for (int j = i + 1; j < n; ++j) {
  17. swap(matrix[i][j], matrix[j][i]);
  18. }
  19. reverse(matrix[i].begin(), matrix[i].end());
  20. }
  21. }
  22. };

买卖股票的最佳时机2

股票衡量是否为利润是基于前一天的价格和今天的价格来比较的,知道这个就好做了。

  1. class Solution {
  2. public:
  3. int maxProfit(vector<int>& prices) {
  4. int l = prices.size();
  5. if(l <= 0) {
  6. return 0;
  7. }
  8. int max = 0;
  9. for(int i=1; i<l; i++) {
  10. if(prices[i] - prices[i-1] > 0) {
  11. max += (prices[i] - prices[i-1]);
  12. }
  13. }
  14. return max;
  15. }
  16. };

LeetCode初级算法(数组)解答的更多相关文章

  1. LeetCode初级算法--数组01:只出现一次的数字

    LeetCode初级算法--数组01:只出现一次的数字 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn. ...

  2. LeetCode初级算法--数组02:旋转数组

    LeetCode初级算法--数组02:旋转数组 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net/ ...

  3. [LEETCODE] 初级算法/数组 1.3旋转数组

    原题: 给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数. 示例 1: 输入: [1,2,3,4,5,6,7] 和 k = 3 输出: [5,6,7,1,2,3,4] 解释: 向右 ...

  4. [LEETCODE] 初级算法/数组 1.1删除排序数组中的重复项

    题目: 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成. ...

  5. LeetCode初级算法的Python实现--数组

    LeetCode初级算法的Python实现--数组 # -*- coding: utf-8 -*- """ @Created on 2018/6/3 17:06 @aut ...

  6. LeetCode初级算法--设计问题01:Shuffle an Array (打乱数组)

    LeetCode初级算法--设计问题01:Shuffle an Array (打乱数组) 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:h ...

  7. LeetCode初级算法之数组:48 旋转图像

    旋转图像 题目地址:https://leetcode-cn.com/problems/rotate-image/ 给定一个 n × n 的二维矩阵表示一个图像. 将图像顺时针旋转 90 度. 说明: ...

  8. LeetCode初级算法的Python实现--排序和搜索、设计问题、数学及其他

    LeetCode初级算法的Python实现--排序和搜索.设计问题.数学及其他 1.排序和搜索 class Solution(object): # 合并两个有序数组 def merge(self, n ...

  9. 【LeetCode算法】LeetCode初级算法——字符串

      在LeetCode初级算法的字符串专题中,共给出了九道题目,分别为:反转字符串,整数反转,字符串中的第一个唯一字符,有效的字母异位词,验证回文字符串,字符串转换整数,实现strStr(),报数,最 ...

随机推荐

  1. Arc071_F Infinite Sequence

    传送门 题目大意 给定一个数$n$,构造一个无限长的序列$A$,使得 $\forall i,j\geq n,A_i=A_j$ $\forall i<j<k\leq i+a_i,A_j=A_ ...

  2. yarn 官方配置推荐

    http://docs.hortonworks.com/HDPDocuments/HDP2/HDP-2.6.4/bk_installing_manually_book/content/rpm-chap ...

  3. poj3585 Accumulation Degree[树形DP换根]

    思路其实非常简单,借用一下最大流求法即可...默认以1为根时,$f[x]$表示以$x$为根的子树最大流.转移的话分两种情况,一种由叶子转移,一种由正常孩子转移,判断一下即可.换根的时候由頂向下递推转移 ...

  4. Git远程克隆仓库出现Permission denied (publickey)

    $ git clone git@github.com:DavidWanderer/test1.git Cloning into 'test1'... Warning: Permanently adde ...

  5. jraiser小结

    1 合并小结 jrcpl F:\site\js\app --settings package.settings 上面代码的意思,就是说,根据package.settings文件,来对app文件夹下的所 ...

  6. JS性能之setTimeout与clearTimeout

    测试环境: chrome浏览器 结论: 1 一个页面用setTimeout越多,该页面消耗的内存就会越多,几乎成正比. 2 在'startCount(1000000);-->100万'情况下,不 ...

  7. 一个Web结合Mybatis项目

    需要引入apache.commons.dbcp-1.2.2.osgi.jar以及org.apache.commons.pool-1.5.3.jar用来提供JDBC的访问: 需要org.springfr ...

  8. Tournament

    题意: 有 $n$ 个 $K$ 维向量,若向量A只要有任意一维大于向量B,则认为A可能打败B,将n个向量一个一个加入,求问对于每次加完后的向量集合:有几个向量可能活到最后. 解法: 考虑如果A可以打败 ...

  9. netty+mqtt

    package io.mqtt.server; import io.mqtt.tool.ConfigService;import io.netty.bootstrap.ServerBootstrap; ...

  10. IDEA拷贝git上的最新项目资源

    File->new ->project version control->git-> 进入项目git对应的网址,选择第一个backstop,复制url: 输入git用户名和密码 ...