暴力递归尝试

1:汉诺塔问题​​​​​

面试题 08.06. 汉诺塔问题 - 力扣(LeetCode) (leetcode-cn.com)暴力递归尝试https://leetcode-cn.com/problems/hanota-lcci/

class Solution {
public:
void zhuanYi(int i,vector<int>&from,vector<int>&other,vector<int>&to){
    if(i==1){int ding=from.back();from.pop_back();to.push_back(ding);}
    else{
        zhuanYi(i-1,from,to,other);//from搬到other
        int ding=from.back();
        from.pop_back();
        to.push_back(ding);
        cout<<"i-1是"<<i-1<<endl;
        cout<<other.size()<<endl;
        zhuanYi(i-1,other,from,to);
    }
}
    void hanota(vector<int>& A, vector<int>& B, vector<int>& C) {
        zhuanYi(A.size(),A,B,C);
    }
};

2:全排列(使用“分支限界”提前杀死重复的路,实现不重复)(不开辟新的数组,直接在原数组位置上改变)

Loading Question... - 力扣(LeetCode) (leetcode-cn.com)暴力递归尝试https://leetcode-cn.com/problems/permutations-ii/submissions/

class Solution {
public:
        void xunhuan(vector<int>&nums,int i,vector<vector<int>>&result){
            if(i==nums.size()){
                result.push_back(nums);return;
            }
            unordered_set<int>xi;
            for(int j=i;j<nums.size();j++){
                if(xi.count(nums[j])!=0){continue;}
                xi.insert(nums[j]);
                //哈希的三个函数:插入inseret,擦除erase,计数count,
                //寻找find:判断有无map.find(key) == map.end(),
                swap(nums[i],nums[j]);
                xunhuan(nums,i+1,result);
                swap(nums[i],nums[j]);
            }
        }

    vector<vector<int>> permuteUnique(vector<int>& nums) {
        vector<vector<int>>result;
        xunhuan(nums,0,result);
        return result;
    }
};

元素的全排列以最简单的三元素为例可以大概描述成,先固定前几位,再交换后两位。

多元素的全排列思路也大概如此,

将第i位后面的各个元素分别和当前的i元素进行交换,也就是i及其以后的各个元素都可以轮流做i的这个位置。对i的位置的各个子情况同样的方法进行下一元素的任命处理。直到处理到尾部了便是处理好了一种结果,逐步递归。

同时为了不产生重复结果(所谓的重复结果主要是因为数组中有相同元素,这样会造成相同元素都做过了一个位子)

在对第i个位子进行子情况遍历时,设立哈希set存储第i个位置谁已经做过了,防止重复。

相比于将所有结果得到去掉重复的方法来说,指标上没有优化(最差情况下没有优化),但是常数项上有优化。

另:哈希的三个函数:插入inseret,擦除erase,计数count,
寻找find:判断有无map.find(key) == map.end(),

3:给定一个整型数组arr,代表数值不同的纸牌排成一条线。玩家A和玩家B依次拿走每张纸牌,规定玩家A先拿,玩家B后拿。但是每个玩家每次只能拿走最左或最右的纸牌,玩家A和玩家B都绝顶聪明。请返回最后获胜者的分数。

#include <bits/stdc++.h>

using namespace std;


int s(vector<int>arr, int i, int j);//子函数相互调用时,可以先证明再写具体的

int f(vector<int>arr, int i, int j) { //返回先手
	if (i == j) {
		return arr[i];
	}

	return max( arr[i] + s(arr, i + 1, j), arr[j] + s(arr, i, j - 1));
}

int s(vector<int>arr, int i, int j) {
	if (i == j) {
		return 0;
	}

	return min( f(arr, i + 1, j), f(arr, i, j - 1) );
}

int win(vector<int>arr) {
	if (arr.size() == 0) {
		return 0;
	}

	return max( f(arr, 0, arr.size() - 1), s(arr, 0, arr.size() - 1 ));
}

int main() {
	vector<int>arr;
	int pp;

	while (cin >> pp) {
		arr.push_back(pp);
	}

	//输入结束时输进去一个字符(因为字符不符合向量的属性)来结束输入,或者按ctrl+z结束输入
	//或者加入终止标识符

	return win(arr);
}

4:栈的逆序(不使用新的数据结构)

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

int f(stack<int> &p) { //返回为底部元素,并且向下压
	int ding = p.top();
	p.pop();

	if (p.empty()) {
		return ding;
	} else {
		int last = f(p);
		p.push(ding);
		return last;
	}
}

void reverse(stack<int> &p) {
	if (p.empty()) {
		return;
	}

	int i = f(p); //获得底并且向下压
	reverse(p);
	p.push(i);
}

int main() {
	stack<int>p;
	for (int i = 0; i < 10; i++) {
		p.push(i + 1);
	}
//
//	cout << "输出按照从栈顶向栈底" << endl;
//	stack<int>q;
//	q = p;
//
//	while (!q.empty()) {
//		cout << q.top() << endl;
//		q.pop();
//	}

	reverse(p);
//	cout << "输出按照从栈顶向栈底" << endl;
//
//	while (!p.empty()) {
//		cout << p.top() << endl;
//		p.pop();
//	}

	return 0;
}

5:规定1和A对应、2和B对应、3和C对应…26和Z对应,那么一个数字字符串比如"111”就可以转化为:“AAA”、“KA"和"AK”。给定一个只有数字字符组成的字符串str,请问有多少种转化结果?

暴力递归尝试

 6:给定两个长度都为N的数组weights和values,weights[i]和values[i]分别代表 i号物品的重量和价值。给定一个正数bag,表示一个载重bag的袋子,你装的物品不能超过这个重量。返回你能装下最多的价值是多少?

暴力递归尝试

上一篇:canvas系列---【vue和原生js中canvas图形的绘制】


下一篇:【C++笔记】关于push_back(vector<int>());