[关闭]
@dyk 2015-11-04T00:45:25.000000Z 字数 4382 阅读 442

Problem Solutions

Algorithm Workspace


Two Sum

LeetCode

大意:给定一个整数array,给定一个target,要求找出两个array中的数a,b,要a+b=target
解法:rbtree,hash map

  1. class Solution {
  2. public:
  3. // 其实二分查找也可以,使用RB树也可以,另外题目的对于output的要求并不是十分明确
  4. vector<int> twoSum(vector<int>& nums, int target) {
  5. int query,count;
  6. vector<int> v(2);
  7. map<int,int> mymap;
  8. vector<int>::iterator it;
  9. map<int,int>::iterator fit;
  10. it = nums.begin();
  11. for(count = 1; it != nums.end(); it++, count++){
  12. mymap.insert(pair<int,int>(*it,count));
  13. }
  14. for(count = 1, it = nums.begin() ; it != nums.end(); it++, count++){
  15. //cout<<"Now query "<<*it<<endl;
  16. query = target - *it;
  17. fit = mymap.find(query);
  18. if(fit != mymap.end()){
  19. //cout<<"in"<<endl;
  20. if(count < fit->second){
  21. v[0] = count;
  22. v[1] = fit->second;
  23. break;
  24. }else if(count > fit->second){
  25. v[1] = count;
  26. v[0] = fit->second;
  27. break;
  28. }
  29. }
  30. }
  31. return v;
  32. }
  33. };

Lisp Expression Explainer

hinocoder , 2015-09-16年网易游戏开发第三题

建立操作符栈,以及操作数栈,并且记录每个括号内的操作数个数。

Input Examples:
5
(+ 1 (* 2 3)))
(2 3)
(- 3 2 1)
(+ (+ 1 2) (* 2 3) (- 2 1))
(- 2)

Output Examples:
invalid expression
invalid expression
invalid expression
10
-2
  1. #include <iostream>
  2. #include <cstdio>
  3. #include <stack>
  4. #include <fstream>
  5. using namespace std;
  6. int main()
  7. {
  8. int casenm;
  9. stack<char> op_stack;
  10. stack<int> opd_stack;
  11. stack<int> opdn_stack;
  12. char op;
  13. int opd , opdn, ans;
  14. char exp[1000001];
  15. int flag = 1;
  16. ifstream ifs;
  17. ifs.open("./input.txt");
  18. if(!ifs){
  19. return 0;
  20. }
  21. ifs>>casenm;
  22. ifs.getline(exp,1000000);
  23. //cin>>casenm;
  24. //cin.getline(exp,1000000);
  25. for(int k = 0; k < casenm ; k++){
  26. // cin.getline(exp,1000000);
  27. ifs.getline(exp,1000000);
  28. flag = 1;
  29. opd = -1;
  30. opdn = 0;
  31. while(!op_stack.empty()){
  32. op_stack.pop();
  33. }
  34. while(!opd_stack.empty()){
  35. opd_stack.pop();
  36. }
  37. while(!opdn_stack.empty()){
  38. opdn_stack.pop();
  39. }
  40. for(int i = 0; exp[i] != '\0' ; i++){
  41. if( exp[i] == '(' || exp[i] == '+' || exp[i] == '-' || exp[i] == '*' ){
  42. op_stack.push(exp[i]);
  43. if(exp[i] == '('){
  44. opdn_stack.push(opdn);
  45. opdn = 0;
  46. if(opd != -1){
  47. // 操作数连着左括号的情况
  48. opd_stack.push(opd);
  49. opdn++;
  50. opd = -1;
  51. }
  52. }
  53. }else if(exp[i] == ')'){
  54. //开始退站计算, 减号只能有2以下个参数 ,加号至少有 1个参数 , 乘号至少有 2 个
  55. if(op_stack.empty()){
  56. // 如果符号栈空则错误
  57. flag = 0;
  58. break;
  59. }else{
  60. op = op_stack.top();
  61. op_stack.pop();
  62. }
  63. //如果存在操作数先将操作数进栈
  64. if(opd != -1){
  65. opd_stack.push(opd);
  66. opd = -1;
  67. opdn++;
  68. }
  69. if(op == '-'){
  70. //
  71. if(opdn == 2){
  72. ans = opd_stack.top();
  73. opd_stack.pop();
  74. ans = opd_stack.top() - ans;
  75. opd_stack.pop();
  76. }else if(opdn == 1){
  77. ans = -1 * opd_stack.top();
  78. opd_stack.pop();
  79. }else if(opdn > 2){
  80. flag = 0;
  81. break;
  82. }
  83. }else if(op == '+'){
  84. ans = 0;
  85. for(int i = 0; i < opdn ; i++){
  86. ans = ans + opd_stack.top();
  87. opd_stack.pop();
  88. }
  89. }else if(op == '*'){
  90. if(opdn < 2){
  91. flag = 0;
  92. break;
  93. }else{
  94. ans = 1;
  95. for(int i = 0; i < opdn ; i++){
  96. ans = ans * opd_stack.top();
  97. opd_stack.pop();
  98. }
  99. }
  100. }else if(op == '('){
  101. //没有操作符的情况
  102. flag = 0;
  103. break;
  104. }
  105. if( !op_stack.empty() && op_stack.top() == '('){
  106. op_stack.pop();
  107. }else if(!op_stack.empty() && op_stack.top() != '('){
  108. // 反向括号不对应的情况 对应了其他符号
  109. flag = 0;
  110. break;
  111. }else if(op_stack.empty()){
  112. // 反向括号不对应的情况 没有对应了其他符号
  113. flag = 0;
  114. break;
  115. }
  116. // 一个括号的运算结果入栈,这个结果可能被上一层的括号使用
  117. opd_stack.push(ans);
  118. if(!opdn_stack.empty()){
  119. // 将上一层opdn的数量弹出
  120. opdn = opdn_stack.top();
  121. opdn_stack.pop();
  122. }else{
  123. flag = 0;
  124. break;
  125. }
  126. opdn++; // 上一层的opd数量+ 1
  127. opd = -1;
  128. }else if(exp[i] >= '0' && exp[i] <= '9'){
  129. if(opd == -1){
  130. // opd 开始情况
  131. opd = 0;
  132. }
  133. opd = opd * 10 + exp[i] - '0';
  134. }else if(exp[i] == ' '){
  135. if(opd != -1){
  136. // 空格情况,如果存在opd则将其入栈
  137. opd_stack.push(opd);
  138. opdn++;
  139. opd = -1;
  140. }
  141. }
  142. // else if(exp[i] == '\0' || 0){
  143. // if(opd != -1){
  144. // opd_stack.push(opd);
  145. // opdn++;
  146. // opd = -1;
  147. // }
  148. // }
  149. }
  150. if(op_stack.empty()){
  151. if( opdn == 1 && flag != 0){
  152. printf("%d\n", opd_stack.top() );
  153. }else{
  154. printf("invalid expression\n");
  155. }
  156. }else{
  157. printf("invalid expression\n");
  158. }
  159. }
  160. return 0;
  161. }

ZigZag Conversion

给一个字符串,以及row数(行数)。摆出N行的,之后在一行一行的输入。
根据N型的特点计算每一个位置的字符。

  1. class Solution {
  2. public:
  3. string convert(string s, int numRows) {
  4. int len = s.length();
  5. int tmp, dis;
  6. dis = 2 * numRows - 2;
  7. if(dis == 0)
  8. // 处理字符长度为1的情况
  9. dis = 1;
  10. char ans[len+1];
  11. ans[len] = '\0';
  12. for(int i = 0, cnt = 0 ; i < numRows ; i++){
  13. if( i == 0 ){
  14. tmp = 0;
  15. while(tmp < len){
  16. ans[cnt++] = s[tmp];
  17. tmp = tmp + dis;
  18. }
  19. }else if(i == numRows - 1){
  20. tmp = numRows - 1;
  21. while(tmp < len){
  22. ans[cnt++] = s[tmp];
  23. tmp = tmp + dis;
  24. }
  25. }else{
  26. tmp = 0;
  27. while(tmp - i < len){
  28. if(tmp - i > 0){
  29. ans[cnt++] = s[tmp-i];
  30. }
  31. if(tmp + i < len){
  32. ans[cnt++] = s[tmp+i];
  33. }
  34. tmp = tmp + dis;
  35. }
  36. }
  37. }
  38. return ans;
  39. }
  40. };

Reverse Integer

将给定的int反转后输出,例如123输出321。符号相同。
唯一需要注意的一点就是反转之后数字可能会溢出int。
判断两个int溢出的方法可以反向验证,例如
A=B+C,是否溢出只需要验证A-B=C?。其他计算式同理。

  1. class Solution {
  2. public:
  3. int reverse(int x) {
  4. int ans, flag;
  5. ans = 0;
  6. if(x < 0){
  7. flag = -1;
  8. x = x * flag;
  9. }
  10. else flag = 1;
  11. while(x){
  12. ans = ans*10 + x%10;
  13. if(ans - x%10 != (ans/10)*10)
  14. return 0;
  15. x = x/10;
  16. }
  17. return flag*ans;
  18. }
  19. };

判断计算是否越界

可以在计算之前先试用INT_MAX或者INT_MIN对计算进行判断。
例如

  1. if(flag == 1){
  2. if(ans > INT_MAX / 10){
  3. return INT_MAX;
  4. }else if(ans > (INT_MAX - (str[k] - '0') * flag )/10 )
  5. return INT_MAX;
  6. }else if(flag == -1){
  7. if(ans < INT_MIN / 10){
  8. return INT_MIN;
  9. }else if(ans < (INT_MIN - (str[k] - '0') * flag)/10)

水仙花问题

水仙花字符串,可以采用遍历所有的可能字串进行判断,当然字串需要划分是偶数串还是奇数串进行判断。

水仙花数,在没有额外空间的情况下判断一个数是不是水仙花数。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注