滑动窗口的最大值,矩阵中的路径,机器人的运动范围,剪绳子(剑指offer65-68)c++版本

#include <iostream>
#include <vector>
#include <deque>

using namespace std;

class Solution {
public:
	//JZ65 滑动窗口的最大值
	vector<int> maxInWindows(const vector<int>& num, unsigned int size);
	//JZ66 矩阵中的路径
	bool hasPath(char* matrix, int rows, int cols, char* str);
	bool hasPathcore(char* matrix, int rows, int cols, char* str, int row, int col, int &strindex, int* &isarrise);
	//JZ67 机器人的运动范围
	int movingCount(int threshold, int rows, int cols);
	int movingCountCore(int threshold, int rows, int cols, int row, int col, int* &isarrise);
	bool issatisfydigits(int threshold, int row, int col);
	//JZ68 剪绳子
	int cutRope(int number);
};
//JZ65 滑动窗口的最大值
vector<int> Solution::maxInWindows(const vector<int>& num, unsigned int size) {
	//队列实现,队首始终是滑动窗口的最大值;或者使用set解决
	int len = num.size();
	if (len < size || size <= 0)	return vector<int>();
	vector<int> result;
	deque<int> que;//队列中存储的是数组中元素的下标
	for (int i = 0; i < size; i++) {
		//如果滑动窗口中前面的数小于后面的数,那么队首不可能成为后面滑动窗口中的最大值
		while (!que.empty() && num[que.back()] <= num[i]){
			que.pop_back();
		}
		que.push_back(i);
	}
	for (int i = size; i < len; i++) {
		result.push_back(num[que.front()]);
		while (!que.empty() && num[que.back()] <= num[i]) {
			que.pop_back();
		}
		que.push_back(i);
		if (i - que.front() >= size)
			que.pop_front();
	}
	result.push_back(num[que.front()]);
	return result;
}
//JZ66 矩阵中的路径
bool Solution::hasPath(char* matrix, int rows, int cols, char* str) {
	//回溯法
	if (!matrix || rows <= 0 || cols <= 0 || !str)	return false;
	bool result = false;
	int *isarrise = new int[rows*cols]();//标记是否出现过。初始化为0
	int strindex = 0;//记录str中匹配的当前位置
	for (int row = 0; row < rows; row++) {
		for (int col = 0; col < cols; col++) {
			if (hasPathcore(matrix, rows, cols, str, row, col, strindex, isarrise))	return true;
		}
	}
	delete[] isarrise;
	return false;
}
bool Solution::hasPathcore(char* matrix, int rows, int cols, char* str, int row, int col, int &strindex, int* &isarrise) {
	if (str[strindex] == '\0')	return true;
	bool result = false;
	int index = row * cols + col;
	if (row >=0 && col >= 0 && row < rows && col < cols && isarrise[index] == 0 && matrix[index] == str[strindex]) {
		isarrise[index] = 1;
		strindex++;
		result = hasPathcore(matrix, rows, cols, str, row + 1, col, strindex, isarrise) || hasPathcore(matrix, rows, cols, str, row, col + 1, strindex, isarrise) ||
			hasPathcore(matrix, rows, cols, str, row - 1, col, strindex, isarrise) || hasPathcore(matrix, rows, cols, str, row, col - 1, strindex, isarrise);
		if (!result) {
			isarrise[index] = 0;
			strindex--;
		}
	}
	return result;
}
//JZ67 机器人的运动范围
int Solution::movingCount(int threshold, int rows, int cols) {
	//回溯法
	if (threshold < 0 || rows <= 0 || cols <= 0)	return 0;
	int* isarrise = new int[rows * cols]();//判断是否走过这个格子
	int result = movingCountCore(threshold, rows, cols, 0, 0, isarrise);
	delete[] isarrise;
	return result;
}
int Solution::movingCountCore(int threshold, int rows, int cols, int row, int col, int* &isarrise) {
	int index = row * cols + col;
	if (row >= rows || col >= cols || row < 0 || col < 0 || isarrise[index] == 1)	return 0;
	int result = 0;
	if (issatisfydigits(threshold, row, col)) {
		result++;
		isarrise[index] = 1;
		result += movingCountCore(threshold, rows, cols, row + 1, col, isarrise) + movingCountCore(threshold, rows, cols, row , col+1, isarrise)
			+ movingCountCore(threshold, rows, cols, row - 1, col, isarrise) + movingCountCore(threshold, rows, cols, row, col-1, isarrise);
	}
	return result;
}
bool Solution::issatisfydigits(int threshold, int row, int col) {
	int temp = 0;
	while (row) {
		temp += row % 10;
		row /= 10;
	}
	while (col) {
		temp += col % 10;
		col /= 10;
	}
	if (temp <= threshold)	return true;
	else
		return false;
}
//JZ68 剪绳子
int Solution::cutRope(int number) {
	//递归法。f(n) = max{f(i)f(n-i)}
	if (number <= 1)	return 0;
	if (number == 2)	return 1;
	if (number == 3)	return 2;
	int* result = new int[number];
	result[0] = 1;
	result[1] = 2;
	result[2] = 3;
	for (int i = 3; i < number; i++) {
		int max;
		if (i == number - 1)	max = 0;
		else
		{
			max = i;
		}
		for (int j = 0; j < (i/2 + 1); j++) {
			int temp = result[j] * result[i - j - 1];
			max = temp > max ? temp : max;
		}
		result[i] = max;
	}
	return result[number - 1];
}



//JZ65 滑动窗口的最大值
void test1() {
	const vector<int> num = { 2,3,4,2,6,2,5,1 };
	int size = 3;
	Solution s;
	vector <int> result = s.maxInWindows(num, size);
	for (vector<int>::iterator it = result.begin(); it != result.end(); it++)
		cout << *it << ' ';
	return;
}
//JZ66 矩阵中的路径
void test2() {
	char* matrix = "abcesfcsadee";
	char* str = "bcced";
	char* str_1 = "abcd";
	int rows = 3;
	int cols = 4;
	Solution s;
	cout << s.hasPath(matrix, rows, cols, str) << endl;
	cout << s.hasPath(matrix, rows, cols, str_1);
	return;
}
//JZ67 机器人的运动范围
void test3() {
	int threshold = 4;
	int rows = 3;
	int cols = 3;
	Solution s;
	cout << s.movingCount(threshold, rows, cols);
	return;
}
//JZ68 剪绳子
void test4() {
	int number = 8;
	Solution s;
	cout << s.cutRope(number);
	return;
}


int main() {
	//test1();
	//test2();
	//test3();
	test4();
	system("pause");
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值