code freethinking--数组 * 重点笔记 *核心代码*

数组理论基础

数组下标从0开始,数组在内存中连续存放

删除需要后面对前进行覆盖

二分查找

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

二分法使用前提:数组有序并且无重复元素

二分法的难点及核心:对于区间的管理,左闭右开还是左闭右闭

左闭右闭:left<=right 并且当middle > target 时候  right = middle-1

同理,左闭右开:left<right  并且当middle > target 时候  right = middle

  • 时间复杂度:O(log n)
  • 空间复杂度:O(1)
#include<iostream>
#include<vector>
using namespace std;

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

移除元素

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。例如给定 nums = [0,1,2,2,3,0,4,2], val = 2, 函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。

快速的方法是使用双指针法,通过一个for循环完成,快指针负责找到每个不等于val的元素并赋值给慢指针。慢指针指向新地址并向前移动,更新数组下标。

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

有序数组的平方

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

核心点是数组是有序的,平方排序关键是取绝对值的最大数,所以对于有序数组一定是两头绝对值大,中间小的。故可以用双指针法,从两头比较得出较大的放在新数组里。

时间复杂度O(N);

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

class Solution {
public:
	vector<int> sortedSquares(vector<int>& nums)
	{
		int M = nums.size() - 1;
		vector<int>result(nums.size(), 0);
			for (int i = 0, j = nums.size() - 1; i <= j;)
			{
				if (nums[i] * nums[i] < nums[j] * nums[j])
				{
					result[M--] = nums[j] * nums[j];
					j--;
				}
				else
				{
					result[M--] = nums[i] * nums[i];
					i++;
				}
			}
		return result;
		
	}
};

长度最小的子数组

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

滑动窗口的入门解决方法。用J开始滑动并计算和sum+=nums[j]一旦发现超过target,则计算子串长度,并引入i 进行向前移动缩小窗口的滑动模式,然后通过巧妙地sum-=nums[i++]不断对符合要求的窗口进行i++的减小,直到在上一步的判断中,找到最小的result,注意最开始给result赋值一个最大的数,如果没有最小的符合要求则只取0的判断。

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int result = INT32_MAX;
        int i=0;
        int sum=0;
        int subLenth =0;
        for(int j=0;j<nums.size();j++)
        {
            sum+= nums[j];
            while(sum>=target)
            {
                subLenth = (j-i+1);
                result = result<subLenth?result :subLenth;
                sum-=nums[i++];
            }
        }
        return result == INT32_MAX ? 0 :result;
    }
};

螺旋矩阵

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

这题主要在用代码模拟过程,不涉及算法思路,主要涉及每一圈上下左右旋转时候,是否做到了闭开区间

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

class Solution {
public:
		vector<vector<int>>gm(int n) {
		vector<vector<int>>res(n, vector<int>(n, 0));
		int startx = 0, starty = 0;
		int loop = n / 2;
		int mid = n / 2;
		int count = 1;
		int offset = 1;
		int i, j;
		while (loop--) {
			i = startx;
			j = starty;
			for (j; j < n - offset; j++) {
				res[i][j] = count++;
			}
			for (i; i < n - offset; i++) {
				res[i][j] = count++;
			}
			for (; j > starty; j--) {
				res[i][j] = count++;
			}
			for (; i > startx; i--) {
				res[i][j] = count++;
			}
			startx++;
			starty++;
			offset += 1;
		}
		if (n % 2) {
			res[mid][mid] = count;
		}
		return res;
	}
};

猜你喜欢

转载自blog.csdn.net/weixin_71572744/article/details/140466852