LeetCode初级算法学习——数组(二)

①两个数组的交集||

题目大意:

给定两个数组,给出交集

思路:

先对两个数组进行排序,从一个数组出发,对另一个数组进行二分查找,直接使用lower_bound函数(找到第一个大于等于的迭代器位置并返回),现在有两种可能,一种是没有找到对应的数。
比如说在A数组为【3,5】,B数组为【1,2,5,7】
则查A数组中的3时,由于没有找到3,则会返回5对应的迭代器位置,这时就进行判断是否没查找到(即找到了b.end()的迭代器位置),还是没有找到了一个数,但是不等于A数组中要查找的数组(在这个例子中为3),这两种情况都导致不会将此数加入并集。只有找到了对应的数字才会加入并集。

这里还需要特判两个个特例,如A数组为【2,2】,B数组为【1,2,2】,则并集为【2,2】。若A数组为【1,2】,B数组为【2,2】,并集为【2】。所以需要用一个time数组来记录对应数字在A数组中出现的次数,在B数组调用二分查找后,根据已出现次数来向后继续查对应数。
如A数组中有两个2,在查到第二个2时,需要在B数组调用二分查找后,再向后推一个位置,判断这个位置的数字是否为2。若为2则B数组至少有两个2,都加入并集,否则则只有一个2,这个2不能加入并集。

源代码:
class Solution {
public:
    vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
        int n2 = nums2.size();
        int n1 = nums1.size();
        sort(nums1.begin(),nums1.end());
        sort(nums2.begin(),nums2.end());
        vector<int> res;
        vector<int> time(1005);
        for(int i=0;i<n1;++i)
        {
            vector<int>::iterator it;
            it = lower_bound(nums2.begin(),nums2.end(),nums1[i]);
            for(int j = 1;j<=time[nums1[i]];++j)
            {
                if(it==nums2.end())
                {
                    break;
                }
                ++it;
            }
            ++time[nums1[i]];
            if(it!=nums2.end() && *it == nums1[i])
            {
                res.emplace_back(nums1[i]);
            }
        }
        return res;
    }
};

②加1

题目大意:

给定一个字符型数组,其代表一个数,将这个数进行加1

思路:

不用想的太复杂,直接进行计算即可,若为9,则变0继续向前循环。若不为9,则该数+1停止循环。若全部为9,则重新先建一个数组,让第一位为1即可

源代码:
class Solution {
public:
    vector<int> plusOne(vector<int>& digits) {
        int n = digits.size();
        for(int i=n-1;i>=0;--i)
        {
            if(digits[i] == 9)
            {
                digits[i] = 0;
            }
            else
            {
                ++digits[i];
                return digits;
            }
        }
        vector<int> res(n+1);
        res[0] = 1;
        return res;
    }
};

③移动零

题目大意:

将数组中的0全部放到后面去,剩余数字相对位置不变

思路:

双指针,遇到0自动跳过,在把所有非零数字放入后,最后只需要全变0即可

源代码:
class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int move = 0;
        int n = nums.size();
        for(int i=0;i<n;++i)
        {
            if(nums[i]!=0)
            {
                nums[move] = nums[i];
                ++move;
            }
        }
        for(int i=move;i<n;++i)
        {
            nums[i] = 0;
        }
    }
};

④两数之和

题目大意:

给定一个数组和一个目标值,找到和为目标值的两个数组元素

思路:

用一个unordered_map做字典,由于是两个数之和,所以可以一边扩充字典,一边查找字典(而无需开始就把字典全部导入)。如2+3=5,在遍历2时未找到,把2加入字典,在遍历3时就会找到2,就可以返回答案了

源代码:
class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int,int> ma;
        int n = nums.size();
        for(int i = 0;i<n;++i)
        {
            if(ma.find(target-nums[i])!=ma.end())
            {
                return vector<int>{i,ma[target-nums[i]]};
            }
            ma.insert(pair<int,int>(nums[i],i));
        }
        return{0};
    }
};

⑤有效的数独

题目大意:

给定一个9 * 9的方格,将其划分为9个3 * 3的小方格,要求每一列、每一行、每一个小方格内若每个数字出现次数均不大于1次,则视为有效数独,否则无效。若出现“.”,则说明待定,不影响数字出现次数

思路:

分别判断,没啥好说的(即使是这样,我也依旧一直RE,查不到问题,所以这里稍微改了一下题解的代码和思路) 直接每一行,每一列,每一个小方格判断即可,用一个数组来记录出行次数,重点在于如何判断每一个小方格的处理上(也可以直接暴力枚举9种情况)

源代码:
class Solution {
public:
    bool isValidSudoku(vector<vector<char>>& board) {
    vector<vector<int>> row(9,vector<int>(9));
    vector<vector<int>> col(9,vector<int>(9));
    vector<vector<int>> box(9,vector<int>(9));
	for (int i = 0; i < 9; i++)
	{
		for (int j = 0; j < 9; j++)
		{
			int box_index = i / 3 * 3 + j / 3;
            if(board[i][j] == '.')
            {
                continue;
            }
			int temp = board[i][j]-'0'-1;
			if (row[i][temp]==1 || col[j][temp]==1 || box[box_index][temp]==1) return false;
			++row[i][temp];
			++col[j][temp];
			++box[box_index][temp];
		}

	}
    return true;
    }
};

⑥旋转图像

题目大意:

把一个n * n的方格(每个小块有一个数字,一共n * n个数字)顺时针翻转90度

思路:

emmm,基本就是一个数学思路,但是我懒得想去优化了,所以直接暴力(性能略差一些)

源代码:
class Solution {
public:
    void rotate(vector<vector<int>>& matrix) {
        int n = matrix.size();
        int x[21][21];
        for(int i=0;i<n;++i)
        {
            for(int j= 0 ;j<n;++j)
            {
                x[i][j] = matrix[i][j];
            }
        }
        for(int i=0;i<n;++i)
        {
            for(int j=0;j<n;++j)
            {
                matrix[i][j] = x[n-j-1][i];
            }
        }
    }
};

终于写完了,期间身体不适(前庭性眩晕,拖了两天进度,之后会保持两天一个专题的更新的)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mac-lengs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值