leetcode题解-初级算法数组篇(6-11题)

继续填坑,本篇文章带来的是leetcode初级算法数组篇6-11题的题解。

第六题 两个数组的交集 II

题目描述:给定两个数组,编写一个函数来计算它们的交集。

示例 1:

输入: nums1 = [1,2,2,1], nums2 = [2,2]
输出: [2,2]
示例 2:

输入: nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出: [4,9]
说明:输出结果中每个元素出现的次数,应与元素在两个数组中出现的次数一致。我们可以不考虑输出结果的顺序

算法说明:建立一个map索引,先遍历nums1数组,并把在map中存储nums1数组中每个元素的个数。然后遍历nums2数组,若该元素出现在map中的值大于0,则把该元素保存到结果中,并且在map中把该值减1。这样的话时间复杂度即扫描与查找,复杂度为O(nlogn),如果用hash map可以优化只O(n)。

实现的代码如下:

class Solution {
public:
    vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
        map<int,int> table;
        vector<int> res;
        for(int i=0;ifor(int i=0;iif(table[nums2[i]]>0) {res.push_back(nums2[i]);table[nums2[i]]--;}
        return res;
    }
};

第七题 加一

题目描述:给定一个非负整数组成的非空数组,在该数的基础上加一,返回一个新的数组。最高位数字存放在数组的首位, 数组中每个元素只存储一个数字。你可以假设除了整数 0 之外,这个整数不会以零开头。
解题算法:一开始看这个题目看错了= =,wa了好多次,这题其实可以看成一个小加法模拟。解题思路就是给最后一位加一,然后判断会不会进位,然后在最高位的时候也要判断一次会不会在加一后等于10,如果是的话在数组前方再添加一位1。只是简单的模拟判断,时间复杂度为O(n)。
实现的代码如下:

class Solution {
public:
    vector<int> plusOne(vector<int>& digits) {
        int c;
        int temp;
        temp=digits[digits.size()-1];
        digits[digits.size()-1]=(digits[digits.size()-1]+1)%10;
        c=(temp+1)/10;
        for(int i=digits.size()-2;i>=0;i--){
        temp=digits[i];
        digits[i]=(digits[i]+c)%10;
        c=(temp+c)/10;
        }
        if(c==1){
            vector<int> res;
            res.push_back(1);
            for(int i=0;i<=digits.size()-1;i++)
                res.push_back(digits[i]);
            return res;
        }
        return digits;
    }
};

第八题 移动零

题目描述:给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
示例:
输入: [0,1,0,3,12]
输出: [1,3,12,0,0]
解题算法:把不是0的数字放到前面,是0的最后加到数组后面就行了,时间复杂度O(n)。
代码:

class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int j=0;
        for(int i=0;iif(nums[i]!=0) nums[j++]=nums[i];
        for(int i=j;j0;
    }
};

第九题 两数之和

题目描述:给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用。示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]

算法说明:我一同学去腾讯面试被问到了原题= =,这题我的思路是这样的建立一个map索引,在扫描数组的时候以值为key,索引位置为value插入到map中,然后扫描的时候观察target减该值的key值是否在map中,在的话直接返回两个的索引即可,不在的话,加入map。时间复杂度最坏的情况下就是O(nlogn),同样可以使用hash map来优化。

代码:

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        map<int,int> mp;
        vector<int> res;
        for(int i=0;imap<int,int>::iterator it;
        for(int i=0;iif(it->second!=i&&it!=mp.end()) {
                res.push_back(i);
                res.push_back(it->second);
                break;
            }
        }
        return res;
    }
};

第十题 有效的数独

题目描述:判断一个 9x9 的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可。

数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。

数独部分空格内已填入了数字,空白格用 ‘.’ 表示。
示例 1:

输入:
[
[“5”,”3”,”.”,”.”,”7”,”.”,”.”,”.”,”.”],
[“6”,”.”,”.”,”1”,”9”,”5”,”.”,”.”,”.”],
[“.”,”9”,”8”,”.”,”.”,”.”,”.”,”6”,”.”],
[“8”,”.”,”.”,”.”,”6”,”.”,”.”,”.”,”3”],
[“4”,”.”,”.”,”8”,”.”,”3”,”.”,”.”,”1”],
[“7”,”.”,”.”,”.”,”2”,”.”,”.”,”.”,”6”],
[“.”,”6”,”.”,”.”,”.”,”.”,”2”,”8”,”.”],
[“.”,”.”,”.”,”4”,”1”,”9”,”.”,”.”,”5”],
[“.”,”.”,”.”,”.”,”8”,”.”,”.”,”7”,”9”]
]
输出: true

解题思路:一道细节题,就是判断横行每个区域的出现次数,所以建立三个数组表来存储即可,用于判断是不是满足每行每列每个区域只出现一次。那么对于n*n的的矩阵扫描一遍即可,时间复杂度为O(n^2)

其实现代码如下:

class Solution {
public:
    bool isValidSudoku(vector<vector<char>>& board) {
        int rowtable[9][9]={0};
        int columtable[9][9]={0};
        int blocktable[9][9]={0};

        for(int i=0;i<9;i++){
            for(int j=0;j<9;j++){              
                if(board[i][j]!='.'){
                char temp=board[i][j]-'1';
                if((rowtable[i][temp]||columtable[j][temp]||blocktable[i/3*3+j/3][temp])==1) return false;
                rowtable[i][temp]=columtable[j][temp]=blocktable[i/3*3+j/3][temp]=1;
            }          
          }
        }
        return true;
    }
};

第十一题 旋转图像

题目描述:给定一个 n × n 的二维矩阵表示一个图像。将图像顺时针旋转 90 度。
说明:
你必须在原地旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要使用另一个矩阵来旋转图像。
示例 1:
给定 matrix =
[
[1,2,3],
[4,5,6],
[7,8,9]
],

原地旋转输入矩阵,使其变为:
[
[7,4,1],
[8,5,2],
[9,6,3]
]

解题算法:因为要求是原地,即不使用额外的复杂度,所以在这个问题上我设置了一个temp,然后找出旋转时,其坐标对应的规律,然后按照题目的要求旋转即可,其代码如下:

class Solution {
public:
    void rotate(vector<vector<int>>& matrix) {
        int temp;
        int l=matrix.size();
        for(int i=0;i2;i++)
            for(int j=i;j1;j++){
                temp=matrix[l-1-j][i];
                matrix[l-1-j][i]=matrix[l-i-1][l-1-j];
                matrix[l-i-1][l-j-1]=matrix[j][l-1-i];
                matrix[j][l-1-i]=matrix[i][j];
                matrix[i][j]=temp;
            }
    }
};

至此初级算法数组篇就全部结束了,之后会更新字符串篇等

你可能感兴趣的:(leetcode)