算法ST笔记——数组

参考:代码随想录

1数组

1.1 二分查找
#include<iostream>
#include<vector>
using namespace std;

class Solution 
{
public:
	int search(vector<int> &vec, int num);
};

int Solution::search(vector<int> &vec, int num)
{
	int left = 0;
	int right = vec.size();  // 这里没有加1
	while (left < right) {  // 这里是小于
		int middle = left + ((right - left) >> 1);  //踏踏实实除以2
		if (num < vec[middle])
		{
			right = middle;
		}
		else if (num > vec[middle])
		{
			left = middle + 1;
		}
		else
		{
			return  middle;  // 这里return
		}
	}
	return -1;
}

int main()
{
	int arr[6] = { 1,3,4,5,8,9 };
	vector<int> vec(arr, arr + 6);
	Solution S;
	cout<<S.search(vec, 9);

	//补充:
	int a = 2 + (3 - 2) >> 1;
	int b = 2 + ((3 - 2) >> 1);
	cout << "a: " << a << endl; // 1
	cout << "b: " << b << endl; // 2

	return 0;
}

注意:有序数组,无重复元素,区间的定义

1.2 移除元素
#include<iostream>
#include<vector>
using namespace std;


class Solution {
public:
	int deleteElem(vector<int> &vec, int num)
	{
		int slowIndex=0, fastIndex=0;
		for (fastIndex = 0; fastIndex < vec.size(); fastIndex++)
		{
			if (vec[fastIndex] != num)
			{
				vec[slowIndex] = vec[fastIndex];
				slowIndex++;
			}
		}
		return slowIndex;
	}

};

int main(int argc,char**argv)
{
	int arr[6] = { 4,5,6,7,7,8 };
	vector<int> vec(arr, arr + 6);
	Solution S;
	int num = S.deleteElem(vec, 7);
	cout << num << endl << endl;
	for (int i = 0; i < num; i++)
	{
		cout << vec[i] << endl;
	}

	return 0;
}

总结:内存地址连续,不能删除元素,只能覆盖;双指针。

1.3 移除元素
#include<iostream>
#include<vector>
using namespace std;


class Solution {
public:
	vector<int> sortElem(vector<int> &input_vec)
	{
		int k = input_vec.size()-1;
		vector<int> output_vec(k+1,0);
		for (int i = 0, j = k; i <= j;)  //取等号是为了把最后一个元素加到output_vec数组里面去
		{
			int start_s = input_vec[i] * input_vec[i];
			int end_s = input_vec[j] * input_vec[j];
			if (start_s < end_s)
			{
				output_vec[k--] = end_s;
				j--;
			}
			else
			{
				output_vec[k--] = start_s;
				i++;
			}
		}
		return output_vec;
	}
};

// 递增数列,平方后排序
int main(int argc, char**argv)
{
	int arr[6] = {-65, -3, 6, 7, 8, 90};
	vector<int> vec(arr, arr + 6);
	Solution S;
	vector<int> out_vec = S.sortElem(vec);
	for (int i = 0; i < out_vec.size(); i++)
	{
		cout << out_vec[i] << endl;
	}

	return 0;
}

总结:从小到大的数组;双指针法,一直指向头一个指向尾;无序:暴力法 – 每个数平方之后,sort排个序

1.4 查找和 ≥ s 的长度最小连续子序列
#include<iostream>
#include<vector>
using namespace std;

class Solution {
public:
	int find(vector<int> vec, int value)
	{
		int i = 0;  //i起始位置
		int sum = 0;
		int len = INT32_MAX;  //字符串长度
		int sub_len = 0;
		
		for (int j = 0; j < vec.size(); j++)  //j滑动位置
		{
			sum += vec[j];
			while (sum >= value)  //等于不能少
			{
				sub_len = j - i + 1;
				len = sub_len < len ? sub_len : len;
				sum -= vec[i++];
			}
		}
		return (len == INT32_MAX ? 0 : len);
	}
};

int main(int argc, char**argv)
{
	int arr[10] = { 1,2,3,4,5,6,11,1,2,3 };//有序, 从小到大,返回坐标
	vector<int> vec(arr, arr + 10);
	Solution S;
	int re = S.find(vec, 50);
	cout << "re: " << re << endl;

	return 0;
}

总结:最终要的是理解两个指针的运作

1.5 螺旋矩阵
#include<iostream>
#include<vector>
using namespace std;

class Solution {
public:
	vector<vector<int>> createCircle(int num)
	{
		int n = num / 2;
		vector<vector<int>> result(num, vector<int>(num, 0));
		int count = 1;
		int start_x = 0, start_y = 0;  //行列
		int i = 0, j = 0;
		int offset = 1;
		while (n--)
		{
			for (j = start_x; j < start_x + num - offset; j++)
			{
				result[start_x][j] = count++;  //一行只写n-1个
			}
			for (i = start_y; i < start_y + num  - offset; i++)
			{
				result[i][j] = count++;
			}
			for (; j > start_x; j--)
			{
				result[i][j] = count++;
			}
			for (; i > start_y; i--)
			{
				result[i][j] = count++;
			}
			start_x++;
			start_y++;
			offset += 2;
		}
		if (num % 2 == 1)
		{
			int mid = num / 2;
			result[mid][mid] = count;
		}
		return result;
	}			
};	

int main(int argc, char**argv)
{
	Solution S;
	vector<vector<int>> vec = S.createCircle(5);
	for (int i = 0; i < vec.size(); i++)
	{
		for (int j = 0; j < vec[0].size(); j++)
		{
			cout << vec[i][j] << endl;
		}
	}
	return 0;
}

总结:注意考虑起始和终止坐标;举几个高维例子(5,6,7)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值