数组算法练习

1. 二分查找

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,
写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。

示例 1:
输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4

示例 2:
输入: nums = [-1,0,3,5,9,12], target = 2
输出: -1
解释: 2 不存在 nums 中因此返回 -1

#include <iostream>
#include <vector>
using namespace std;

int findElement(const vector<int>& nums, const int target)
{
    // 定义target在左闭右闭的区间里,[left, right]
    int left = 0, right = nums.size() - 1;
    // 边界处理,等不等于的问题: 当left==right,区间[left, right]依然有效,所以用 <=
    while (left <= right)
    {
        int mid = left + (right - left) / 2;
        if (nums[mid] == target) return mid;
        if (nums[mid] < target) left = mid + 1;
        else right = mid - 1;
    }
    return -1;
}

int main()
{
    int target = 9;
    vector<int> arr = {-1,0,3,5,9,12};
    cout << findElement(arr, target) << endl;
    return 0;
}

2. 移除元素

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并原地修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

示例 1:
输入: nums = [3,2,2,3], val = 3
输出: 2
解释: 函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2

示例 2:
输入: nums = [0,1,2,2,3,0,4,2], val = 2
输出: 5
解释: 函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4

#include<iostream>
#include<vector>
using namespace std;

int removeElement(vector<int>& nums, const int val)
{
    // 双指针
    int left = 0;
    for (int right = 0; right < nums.size(); ++right)
    {
        if (nums[right] != val) nums[left++] = nums[right];
    }
    return left;
}

int main()
{
    int val = 2;
    vector<int> arr = {0,1,2,2,3,0,4,2};
    cout << removeElement(arr, val) << endl;
    return 0;
}

3. 有序数组的平方

给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。

示例 1:
输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
解释:平方后,数组变为 [16,1,0,9,100],排序后,数组变为 [0,1,9,16,100]

示例 2:
输入:nums = [-7,-3,2,3,11]
输出:[4,9,9,49,121]

#include<iostream>
#include<vector>
using namespace std;

vector<int> sortedSquares(vector<int>& arr)
{
    vector<int> ans(arr.size());
    // 双指针
    int left = 0, right = arr.size() - 1;
    for (int i = arr.size() - 1; i >= 0; --i)
    {
        int mul1 = arr[left] * arr[left], mul2 = arr[right] * arr[right];
        if (mul1 > mul2)
        {
            ans[i] = mul1;
            ++left;
        }
        else
        {
            ans[i] = mul2;
            --right;
        }
    }
    return ans;
}

void showArr(vector<int>& arr)
{
    cout << "[";
    for(auto n : arr)
    {
        cout << n << ", ";
    }
    cout << "]" << endl;
}

int main()
{
    vector<int> arr = {-5,-3,-2,-1};
    vector<int> ans = sortedSquares(arr);
    showArr(ans);
    return 0;
}

4. 长度最小的子数组

给定一个含有 n 个正整数的数组和一个正整数 s ,
找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。
如果不存在符合条件的子数组,返回 0。

示例:
输入:s = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。

提示:
1 <= target <= 10^9
1 <= nums.length <= 10^5
1 <= nums[i] <= 10^5

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

int findMinSubArr(const int s, const vector<int>& nums)
{
    int sum = 0, count = INT32_MAX;
    // 滑动窗口
    int left = 0;
    int subLen = 0;
    for (int i = 0; i < nums.size(); ++i)
    {
        sum += nums[i];
        // sum 和大于等于 s 时更新 count 长度
        while (sum >= s) 
        {
            subLen = i - left + 1;
            count = min(subLen, count);
            sum -= nums[left++];
        }
    }
    return count == INT32_MAX ? 0 : count;
}

int main()
{
    int s = 7;
    vector<int> arr = {2,3,1,2,4,3};
    cout << findMinSubArr(s, arr) << endl;
    return 0;
}

5. 螺旋矩阵II

给定一个正整数 n,生成一个包含 1 到 n^2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。

示例:
输入: 3
输出: [ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ]

#include<iostream>
#include<vector>
using namespace std;

vector<vector<int>> generateMatrix(const int n)
{
    // 结果存储
    vector<vector<int>> ans(n, vector<int>(n));
    // 计数
    int num = 1;
    // 循环圈数
    int loop = n / 2;
    // 每圈偏移
    int offset = 1; 
    // 圈起始位置
    int x = 0, y = 0;
    while (loop--)
    {
        // ~ 记录行列数 ~
        int i = x;
        int j = y;
        // ~ 记录行列数 ~

        // ~ 开始转圈 ~
        // 左到右(行不变,列变)
        for (j; j < n - offset; ++j)
        {
            ans[i][j] = num++;
        }
        // 上到下(接着列,行变列不变)
        for (i; i < n - offset; ++i)
        {
            ans[i][j] = num++;
        }
        // 右到左(接着行,列变行不变,止步在起始列之前)
        for (; j > y; --j)
        {
            ans[i][j] = num++;
        }
        // 下到上(接着列,行变列不变,止步在起始行之前)
        for (; i > x; --i)
        {
            ans[i][j] = num++;
        }
        // ~ 开始转圈 ~

        // ~ 圈数参数更新 ~
        ++x; // 行起始位置
        ++y; // 列起始位置
        ++offset; // 偏移量
        // ~ 圈数参数更新 ~
    }

    // 如果 n 是奇数,则需要单独处理中间值
    if (n % 2)
    {
        ans[n/2][n/2] = num;
    }

    return ans;
}

void showArr(vector<vector<int>>& nums)
{
    cout << "[ ";
    for (int i = 0; i < nums.size(); ++i)
    {
        cout << "[ ";
        for (int j = 0; j < nums[i].size(); ++j)
        {
            if (j == nums[i].size() - 1) cout << nums[i][j] << " ";
            else cout << nums[i][j] << ", ";
        }
        if (i == nums.size() - 1) cout << "]";
        else cout << "], ";
    }
    cout << " ]" << endl;
}

int main()
{
    int n;
    cin >> n;
    vector<vector<int>> ans;
    ans = generateMatrix(n);
    showArr(ans);
    return 0;
}
posted @   bok_tech  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
  1. 1 翻云覆雨 BLL
  2. 2 与我无关 阿冗
  3. 3 想去海边 夏日入侵企划
  4. 4 没有理想的人不伤心 新裤子
  5. 5 生活因你而火热 新裤子
与我无关 - 阿冗
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.
点击右上角即可分享
微信分享提示