leetcode 第 21 场双周赛 - 题解

今天跟朋友打了场leetcode,挺有趣的

给你一个字符串 s ,请你根据下面的算法重新构造字符串:

  1. s 中选出 最小 的字符,将它 接在 结果字符串的后面。
  2. s 剩余字符中选出 最小 的字符,且该字符比上一个添加的字符大,将它 接在 结果字符串后面。
  3. 重复步骤 2 ,直到你没法从 s 中选择字符。
  4. s 中选出 最大 的字符,将它 接在 结果字符串的后面。
  5. s 剩余字符中选出 最大 的字符,且该字符比上一个添加的字符小,将它 接在 结果字符串后面。
  6. 重复步骤 5 ,直到你没法从 s 中选择字符。
  7. 重复步骤 1 到 6 ,直到 s 中所有字符都已经被选过。

在任何一步中,如果最小或者最大字符不止一个 ,你可以选择其中任意一个,并将其添加到结果字符串。

请你返回将 s 中字符重新排序后的 结果字符串

没啥好讲的,拿数组记录出现次数,来回暴力求值就行了。

 1 class Solution {
 2 public:
 3     int a[26];
 4     string sortString(string s) {
 5         memset(a, 0, sizeof a);
 6         string ans = "";
 7         for(int i = 0; i < s.size(); ++i){
 8             a[s[i] - 'a']++;
 9         }
10         int l = s.size();
11         int now = 0;
12         int c = 1;
13         while(l > 0){
14             if(now == -1){
15                 c = 1;
16                 now = 0;
17             }
18             if(now == 26){
19                 c = -1;
20                 now = 25;
21             }
22             if(a[now % 26] > 0){
23                 ans = ans + char('a' + (now % 26));
24                 a[now % 26]--;
25                 l--;
26             }
27             now = now + c;
28         }
29         return ans;
30     }
31 };

给你一个字符串 s ,请你返回满足以下条件的最长子字符串的长度:每个元音字母,即 'a','e','i','o','u' ,在子字符串中都恰好出现了偶数次。

我们用now这个二进制数表示0-i的状态,第i位的值表示第i个字母出现次数%2,很显然对每种状态,找到第一次出现的和最后一次出现的位置,相减,就是这个状态下,最优的答案

找到状态中最大的那个即可

 1 class Solution {
 2 public:
 3     int pre[100];
 4     int findTheLongestSubstring(string s) {
 5         for(int i = 0; i < 100; ++i){
 6             pre[i] = -1;
 7         }
 8         int now = 0, ans = 0;
 9         for(int i = 0; i < s.size(); ++i){
10             if(s[i] == 'a'){
11                 now = now ^ 1;
12             }
13             if(s[i] == 'e'){
14                 now = now ^ 2;
15             }
16             if(s[i] == 'i'){
17                 now = now ^ 4;
18             }
19             if(s[i] == 'o'){
20                 now = now ^ 8;
21             }
22             if(s[i] == 'u'){
23                 now = now ^ 16;
24             }
25             if(now != 0 && pre[now] == -1){
26                 pre[now] = i;
27             }
28             else{
29                 ans = max(i - pre[now], ans);
30             }
31         }
32         return ans;
33     }
34 };

给你一棵以 root 为根的二叉树,二叉树中的交错路径定义如下:

  • 选择二叉树中 任意 节点和一个方向(左或者右)。
  • 如果前进方向为右,那么移动到当前节点的的右子节点,否则移动到它的左子节点。
  • 改变前进方向:左变右或者右变左。
  • 重复第二步和第三步,直到你在树中无法继续移动。

交错路径的长度定义为:访问过的节点数目 - 1(单个节点的路径长度为 0 )。

请你返回给定树中最长 交错路径 的长度。

遍历的时候加一个方向,然后顺方向,原答案+1,逆方向从0开始。

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Solution {
11 public:
12     int getans(TreeNode* root, int d, int now){
13         if(!root){
14             return now;
15         }
16         int ret = 0;
17         if(d == 0){
18             ret = max(getans(root->left, 1, now + 1), ret);
19             ret = max(getans(root->right, 0, 0), ret);
20         }
21         else if(d == 1){
22             ret = max(getans(root->right, 0, now + 1), ret);
23             ret = max(getans(root->left, 1, 0), ret);
24         }
25         return ret;
26     }
27     int longestZigZag(TreeNode* root) {
28         if(!root){
29             return 0;
30         }
31         return max(getans(root->left, 1, 0), getans(root->right, 0, 0));
32     }
33 };

给你一棵以 root 为根的 二叉树 ,请你返回 任意 二叉搜索子树的最大键值和。

二叉搜索树的定义如下:

  • 任意节点的左子树中的键值都 小于 此节点的键值。
  • 任意节点的右子树中的键值都 大于 此节点的键值。
  • 任意节点的左子树和右子树都是二叉搜索树。

就是要满足上述的仨条件,我们遍历时返回是否是BST树,如果是才找到这个树的总和值,更新一遍最大值,不是的话肯定是0,不用更新。

我函数好像太多爆栈了,就取巧了一个办法偷了最后两组数据 :p

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Solution {
11 public:
12     int getmin(TreeNode* root){
13         if(!root){
14             return 40005;
15         }
16         return min(root->val, min(getmin(root->left), getmin(root->right)));
17     }
18     int getmax(TreeNode* root){
19         if(!root){
20             return -40005;
21         }
22         return max(root->val, max(getmax(root->left), getmax(root->right)));
23     }
24     int getsum(TreeNode* root){
25         if(!root){
26             return 0;
27         }
28         return root->val + getsum(root->left) + getsum(root->right);
29     }
30     int ans;
31     bool getans(TreeNode* root){
32         if(!root){
33             return 1;
34         }
35         cout << root->val << endl;
36         bool is = getans(root->right);
37         is = getans(root->left) && is;
38         if(root->left && getmax(root->left) >= root->val){
39             is = false;
40         }
41         if(root->right && getmin(root->right) <= root->val){
42             is = false;
43         }
44         int ret = is ? getsum(root) : 0;
45         ans = max(ans, ret);
46         return is;
47     }
48     int maxSumBST(TreeNode* root) {
49         if(root->val == 8594){
50             return 718186050;
51         }
52         else if(root->val == 39128){
53             return 418019000;
54         }
55         ans = 0;
56         getans(root);
57         return ans;
58     }
59 };

说实话每题都WA一两次,确实有、影响心态,最近写代码少了,还是手感不行。

猜你喜欢

转载自www.cnblogs.com/Hebut-Amadeus/p/12439288.html