【CODE】next number && stack

目錄

375. Guess Number Higher or Lower II

294.Flip Game II 

739. Daily Temperatures

503. Next Greater Element II

556. Next Greater Element III

394. Decode String

150. Evaluate Reverse Polish Notation


375. Guess Number Higher or Lower II

Medium

681992Add to ListShare

We are playing the Guess Game. The game is as follows:

I pick a number from 1 to n. You have to guess which number I picked.

Every time you guess wrong, I'll tell you whether the number I picked is higher or lower.

However, when you guess a particular number x, and you guess wrong, you pay $x. You win the game when you guess the number I picked.

Example:

n = 10, I pick 8.

First round:  You guess 5, I tell you that it's higher. You pay $5.
Second round: You guess 7, I tell you that it's higher. You pay $7.
Third round:  You guess 9, I tell you that it's lower. You pay $9.

Game over. 8 is the number I picked.
You end up paying $5 + $7 + $9 = $21.

Given a particular n ≥ 1, find out how much money you need to have to guarantee a win.

#include"pch.h"
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
/*Runtime: 20 ms, faster than 77.28% of C++ online submissions for Guess Number Higher or Lower II.
Memory Usage : 9 MB, less than 83.33% of C++ online submissions for Guess Number Higher or Lower II.
https://www.cnblogs.com/grandyang/p/5677550.html*/
int getMoneyAmount(int n) {
	vector<vector<int> > dp(n + 1, vector<int>(n + 1));
	//dp[i][j]
	for (int j=2; j <= n; j++) {
		for (int i=j- 1; i >0; i--) {
			int global_min = INT_MAX;
			for (int k = i+1; k < j; k++) {
				int local_max = k + max(dp[i][k - 1], dp[k + 1][j]);
				global_min = min(global_min, local_max);
			}
			if (i==j-1) dp[i][j] = i;
			else dp[i][j] = global_min;
		}
	}
	return dp[1][n];
}
int main() {
	cout << getMoneyAmount(10);
	return 0;
}

294.Flip Game II 

You are playing the following Flip Game with your friend: Given a string that contains only these two characters: + and -, you and your friend take turns to flip two consecutive "++" into "--". The game ends when a person can no longer make a move and therefore the other person will be the winner.

Write a function to determine if the starting player can guarantee a win.

Example:

Input: s = "++++"

Output: true 
Explanation: The starting player can guarantee a win by flipping the middle "++" to become "+--+"

Follow up:
Derive your algorithm's runtime complexity.

#include"pch.h"
#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
using namespace std;
/*293.Flip Game:將 ++ 變成 --*/
vector<string> generatePossibleNextMoves1(string s) {
	vector<string> res;
	for (int i = 1; i < s.size(); i++) {
		if (s[i] == '+' && s[i - 1] == '+') {
			s[i] = '-'; s[i - 1] = '-';
			res.push_back(s);
			s[i] = '+'; s[i - 1] = '+';
			/*或者是:res.push_back(s.substr(0,i-1)+"--"+s.substr(i+1))*/
		}
	}
	return res;
}
/*294.Flip Game II:是否先手能保證成功*/
bool canWin1(string s) {
	for (int i = 1; i < s.size(); i++) {
		if (s[i] == '+' && s[i - 1] == '+' && !canWin1(s.substr(0, i - 1) + "--" + s.substr(i + 1)))
			return true;
	}
	return false;
	
}
/*如果遇到"+++",變成"+--"
沒有"+++",就改變"++"*/
bool canWin2(string s) {
	int win = 0;//先手,奇數win
	int three = s.find("+++");
	while ( three!= -1) {
		s[three + 1] = '-';
		s[three + 2] = '-';
		//"+++" -> "+--"
		win++;
		three = s.find("+++");
	}
	int two = s.find("++");
	while ( two!= -1) {
		//無"+++"
		s[two] = '-';
		s[two + 1] = '-';
		win++;
		int two = s.find("++");
	}
	if (win % 2 == 1) return true;
	else return false;
}
int main() {
	string s = "+++++++";
	cout << canWin1(s) << endl;
	cout << s << endl;
	cout << canWin2(s) << endl;
	return 0;
}

739. Daily Temperatures

Medium

210266Add to ListShare

Given a list of daily temperatures T, return a list such that, for each day in the input, tells you how many days you would have to wait until a warmer temperature. If there is no future day for which this is possible, put 0 instead.

For example, given the list of temperatures T = [73, 74, 75, 71, 69, 72, 76, 73], your output should be [1, 1, 4, 2, 1, 1, 0, 0].

Note: The length of temperatures will be in the range [1, 30000]. Each temperature will be an integer in the range [30, 100].

#include"pch.h"
#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
#include<stack>
#include<unordered_map>
using namespace std;
/*739. Daily Temperatures*/
/*1.存放每一個溫度出現的位置,例如70之後,只需要找71、72、……、100的位置。
Runtime: 960 ms, faster than 5.07% of C++ online submissions for Daily Temperatures.
Memory Usage: 18.2 MB, less than 8.00% of C++ online submissions for Daily Temperatures.*/
vector<int> dailyTemperatures1(vector<int>& T) {
	unordered_map<int, vector<int> > mp;
	for (int i = 0; i < T.size(); i++) {
		mp[T[i]].push_back(i);
	}
	vector<int> res(T.size());
	for (int i = 0; i < T.size(); i++) {
		int tmp = T[i];
		int minn = 30001;
		for (int j = tmp + 1; j <= 100; j++) {
			if (mp[j].size() > 0 && mp[j].back()>i) {
				int t = upper_bound(mp[j].begin(), mp[j].end(), i) - mp[j].begin();
				cout << mp[j][t] << endl;
				minn = min(minn, mp[j][t] - i);
			}
		}
		if(minn==30001) res[i] =0;
		else res[i] = minn;
	}
	return res;
}
/*2.從結尾遍歷到開頭
Runtime: 208 ms, faster than 28.27% of C++ online submissions for Daily Temperatures.
Memory Usage: 14.7 MB, less than 100.00% of C++ online submissions for Daily Temperatures.*/
vector<int> dailyTemperatures2(vector<int>& T) {
	vector<int> tmp(101);
	vector<int> res(T.size());
	for (int i = 0; i < 101; i++) tmp[i] = INT_MAX;
	for (int i = T.size() - 1; i >= 0; i--) {
		tmp[T[i]] = i;
		int minn = INT_MAX;
		for (int j = T[i] + 1; j <= 100; j++) {
			if(tmp[j]!=INT_MAX) minn = min(tmp[j] - i, minn);
			if (minn == 1) break;
		}
		if (minn == INT_MAX) res[i] = 0;
		else res[i] = minn;
	}
	return res;
}
/*3.棧,棧中存放索引位置,如果當前遍歷到的元素,比棧頂位置對應的元素大,
那麼棧頂對應元素最接近位置的較大元素就是當前遍歷到的元素。
Runtime: 200 ms, faster than 47.88% of C++ online submissions for Daily Temperatures.
Memory Usage: 16.2 MB, less than 52.00% of C++ online submissions for Daily Temperatures.*/
vector<int> dailyTemperatures3(vector<int>& T) {
	stack<int> s;
	vector<int> res(T.size());
	for (int i = 0; i < T.size(); i++) {
		while (!s.empty() && T[i] > T[s.top()]) {
			res[s.top()] = i-s.top();
			s.pop();
		}
		s.push(i);
	}
	return res;
}
int main() {
	vector<int> T = { 73, 74, 75, 71, 69, 72, 76, 73 };
	vector<int> res = dailyTemperatures3(T);
	for (int i = 0; i < res.size(); i++) cout << res[i] << " ";
	return 0;
}

503. Next Greater Element II

Medium

108956Add to ListShare

Given a circular array (the next element of the last element is the first element of the array), print the Next Greater Number for every element. The Next Greater Number of a number x is the first greater number to its traversing-order next in the array, which means you could search circularly to find its next greater number. If it doesn't exist, output -1 for this number.

Example 1:

Input: [1,2,1]
Output: [2,-1,2]
Explanation: The first 1's next greater number is 2; 
The number 2 can't find next greater number; 
The second 1's next greater number needs to search circularly, which is also 2.

Note: The length of given array won't exceed 10000.

#include"pch.h"
#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
#include<stack>
#include<unordered_map>
using namespace std;
/*496. Next Greater Element I
nums1是nums2的子集,在nums2中找第一個大於nums1[i]的數
Runtime: 8 ms, faster than 98.21% of C++ online submissions for Next Greater Element I.
Memory Usage: 9.5 MB, less than 57.89% of C++ online submissions for Next Greater Element I.*/
vector<int> nextGreaterElement1(vector<int>& nums1, vector<int>& nums2) {
	unordered_map<int, int> mp;
	stack<int> s;
	for (int i = 0; i < nums2.size(); i++) {
		while (!s.empty() && nums2[i] > s.top()) {
			mp[s.top()] = nums2[i];
			s.pop();
		}
		s.push(nums2[i]);
	}
	vector<int> res;
	for (int i = 0; i < nums1.size(); i++) {
		if (mp.find(nums1[i]) != mp.end()) res.push_back(mp[nums1[i]]);
		else res.push_back(-1);
	}
	return res;
}
/*503. Next Greater Element II
循環找,找第一個比自己大的數,找不到是-1,[1,2,1]->[2,-1,2]
Runtime: 84 ms, faster than 93.83% of C++ online submissions for Next Greater Element II.
Memory Usage: 12.6 MB, less than 44.44% of C++ online submissions for Next Greater Element II.*/
typedef struct Node {
	int index;
	int value;
}Node;
vector<int> nextGreaterElements2(vector<int>& nums) {
	vector<int> res(nums.size());
	if (nums.size() == 0) return res;
	stack<Node> s;
	int  n = nums.size();
	int i = 0;
	while(true){
		if (i < n) {
			while (!s.empty() && nums[i] > s.top().value) {
				res[s.top().index] = nums[i];
				s.pop();
			}
			Node tmp;
			tmp.index = i; tmp.value = nums[i];
			s.push(tmp);
			i++;
		}
		else if(i%n != s.top().index){
			while (!s.empty() && nums[i%n] > s.top().value) {
				res[s.top().index] = nums[i%n];
				s.pop();
			}
			i++;
		}
		else break;
	}
	while (!s.empty()) {
		res[s.top().index] = -1;
		s.pop();
	}
	return res;
}
int main() {
	vector<int> nums1 = { 1,1,1,1,1 };
	vector<int> res = nextGreaterElements2(nums1);
	for (int i = 0; i < res.size(); i++) cout << res[i] << " ";
	return 0;
}

556. Next Greater Element III

Medium

498152Add to ListShare

Given a positive 32-bit integer n, you need to find the smallest 32-bit integer which has exactly the same digits existing in the integer n and is greater in value than n. If no such positive 32-bit integer exists, you need to return -1.

Example 1:

Input: 12
Output: 21

Example 2:

Input: 21
Output: -1
#include"pch.h"
#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
#include<stack>
#include<unordered_map>
#include<set>
#include<queue>
using namespace std;
/*556. Next Greater Element III
從個位數開始遍歷,入大頂堆,
若當前數≥堆頂,說明堆中沒有比當前元素大的,當前元素入堆,
否則取當前堆中最小的大於當前值的值,並將該值放在當前遍歷到的位置上,當前值入堆,跳出遍歷
需要對上述遍歷到的值及以前的數值,從堆中選取元素,重新加入
例如:460243 —> 數組:tmp={3,4,2,0,6,4}
入堆:3,4,2(當前元素2,堆中有比它大的元素)
將堆中元素3,4存入數組:4,3,利用upper_bound找到第一個比2大的元素:3,堆中:4,2
將原來2的位置上的數換成3:tmp={3,4,3,0,6,4},記錄下替換的位置tar
跳出遍歷,爲剛剛遍歷過的位置重新賦值:堆中由大到小,爲0-(tar-1)重新賦值:{4,2,3,0,6,4}
再倒着計算出res。
這裏有一個陷阱!題目說,不會大於32-bit,所以輸出res時要判斷一下,是否小於32bit,否則返回-1。
Runtime: 0 ms, faster than 100.00% of C++ online submissions for Next Greater Element III.
Memory Usage: 8.4 MB, less than 63.64% of C++ online submissions for Next Greater Element III.*/
int nextGreaterElement(int n) {
	int N = n;
	vector<int> tmp;
	while (n) {
		tmp.push_back(n % 10);
		n /= 10;
	}
	priority_queue<int,vector<int>,less<int> > q;//大頂堆
	vector<int> vec;
	int tar = 0;
	for (int i = 0; i < tmp.size();i++) {
		if (!q.empty()) {
			if (tmp[i] >= q.top()) q.push(tmp[i]);
			else {//優先隊列中有比當前值大的數
				int tmpp = tmp[i];
				while (!q.empty()) {
					vec.push_back(q.top());
					q.pop();
				}
				reverse(vec.begin(), vec.end());
				int index=upper_bound(vec.begin(), vec.end(), tmp[i]) - vec.begin();
				tmp[i] = vec[index];
				vec[index] = tmpp;
				tar = i;
				break;
			}
		}
		else q.push(tmp[i]);
	}
	//vec是升序
	for (int i = tar-1, j = 0; i >=0; i--) {
		tmp[i] = vec[j++];
	}
	long long res = 0, cheng = 1;

	for (int i = 0; i < tmp.size(); i++) {
		res += tmp[i]*cheng;
		cheng *= 10;
	}
	if (res == N) return -1;
	else if (res >= 2147483647) return -1;
	return res;
}
int main() {
	cout<<nextGreaterElement(460243);
	return 0;
}

394. Decode String

Medium

2460125Add to ListShare

Given an encoded string, return its decoded string.

The encoding rule is: k[encoded_string], where the encoded_string inside the square brackets is being repeated exactly k times. Note that k is guaranteed to be a positive integer.

You may assume that the input string is always valid; No extra white spaces, square brackets are well-formed, etc.

Furthermore, you may assume that the original data does not contain any digits and that digits are only for those repeat numbers, k. For example, there won't be input like 3a or 2[4].

Examples:

s = "3[a]2[bc]", return "aaabcbc".
s = "3[a2[c]]", return "accaccacc".
s = "2[abc]3[cd]ef", return "abcabccdcdcdef".
#include"pch.h"
#include<iostream>
#include<stack>
#include<string>
using namespace std;
/*394. Decode String
棧
s = "3[a]2[bc]", return "aaabcbc".
s = "3[a2[c]]", return "accaccacc".
s = "2[abc]3[cd]ef", return "abcabccdcdcdef".
Runtime: 4 ms, faster than 55.62% of C++ online submissions for Decode String.
Memory Usage: 9 MB, less than 62.74% of C++ online submissions for Decode String.*/
string decodeString(string s) {
	string res = "";
	stack<int> n;
	stack<string> c;
	int num = 0;
	for (int i = 0; i < s.size(); i++) {
		if (s[i] >= '0' && s[i] <= '9') num = num * 10 + (s[i] - '0');
		else if (s[i] == '[') {
			c.push("[");
			n.push(num);
			num = 0;
		}
		else if (s[i] == ']') {
			string tmp = "";
			while (!c.empty() && c.top() != "[") {
				tmp += c.top();
				c.pop();
			}
			if (!c.empty() && c.top() == "[") {
				c.pop();
				int numm = n.top();
				n.pop();
				string str =tmp;
				while (--numm) str += tmp;
				c.push(str);
			}
		}
		else {
			string tmpp = "";
			tmpp.push_back(s[i]);
			c.push(tmpp);
		}
	}
	while (!c.empty()) {
		res += c.top();
		c.pop();
	}
	reverse(res.begin(), res.end());
	cout << res << endl;
	return res;
}
int main() {
	cout << decodeString("100[leetcode]");
	system("pause");
	return 0;
}

150. Evaluate Reverse Polish Notation

Medium

809423Add to ListShare

Evaluate the value of an arithmetic expression in Reverse Polish Notation.

Valid operators are +-*/. Each operand may be an integer or another expression.

Note:

  • Division between two integers should truncate toward zero.
  • The given RPN expression is always valid. That means the expression would always evaluate to a result and there won't be any divide by zero operation.

Example 1:

Input: ["2", "1", "+", "3", "*"]
Output: 9
Explanation: ((2 + 1) * 3) = 9

Example 2:

Input: ["4", "13", "5", "/", "+"]
Output: 6
Explanation: (4 + (13 / 5)) = 6

Example 3:

Input: ["10", "6", "9", "3", "+", "-11", "*", "/", "*", "17", "+", "5", "+"]
Output: 22
Explanation: 
  ((10 * (6 / ((9 + 3) * -11))) + 17) + 5
= ((10 * (6 / (12 * -11))) + 17) + 5
= ((10 * (6 / -132)) + 17) + 5
= ((10 * 0) + 17) + 5
= (0 + 17) + 5
= 17 + 5
= 22
#include"pch.h"
#include<iostream>
#include<stack>
#include<string>
#include<vector>
using namespace std;
/*150. Evaluate Reverse Polish Notation
RPN:Reverse Polish Notation,後綴表達式
Runtime: 12 ms, faster than 92.44% of C++ online submissions for Evaluate Reverse Polish Notation.
Memory Usage: 11.6 MB, less than 73.68% of C++ online submissions for Evaluate Reverse Polish Notation.*/
int evalRPN(vector<string>& tokens) {
	stack<int> num;
	for (int i = 0; i < tokens.size(); i++) {
		if (tokens[i] != "-" && tokens[i] != "+" && tokens[i] != "/" && tokens[i] != "*") {
			int n = stoi(tokens[i]);
			num.push(n);
		}
		else {
			int a = num.top();
			num.pop();
			int b = num.top();
			num.pop();
			if (tokens[i] == "-") num.push(b - a);
			else if (tokens[i] == "+") num.push(b + a);
			else if (tokens[i] == "/") num.push(b / a);
			else num.push(b*a);
		}
	}
	return num.top();
}
int main() {
	vector<string> num = { "2", "1", "+", "3", "*" };
	cout << evalRPN(num)<<endl;
	system("pause");
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章