今天跟朋友打了场leetcode,挺有趣的
给你一个字符串 s
,请你根据下面的算法重新构造字符串:
- 从
s
中选出 最小 的字符,将它 接在 结果字符串的后面。 - 从
s
剩余字符中选出 最小 的字符,且该字符比上一个添加的字符大,将它 接在 结果字符串后面。 - 重复步骤 2 ,直到你没法从
s
中选择字符。 - 从
s
中选出 最大 的字符,将它 接在 结果字符串的后面。 - 从
s
剩余字符中选出 最大 的字符,且该字符比上一个添加的字符小,将它 接在 结果字符串后面。 - 重复步骤 5 ,直到你没法从
s
中选择字符。 - 重复步骤 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一两次,确实有、影响心态,最近写代码少了,还是手感不行。