题目描述
给你一个整数 n,请你返回 任意 一个由 n 个 各不相同 的整数组成的数组,并且这 n 个数相加和为 0 。  示例 1: 输入:n = 5 输出:[-7,-1,1,3,4] 解释:这些数组也是正确的 [-5,-1,1,2,3],[-3,-1,2,-2,4]。 示例 2: 输入:n = 3 输出:[-1,0,1] 示例 3: 输入:n = 1 输出:[0]  提示: 1 <= n <= 1000
题解1
产生n个不同的数字和为0的方式有很多种,可以对称产生0左右两边的数。具体 如果$n = 2  m$,则结果为:$-m, -(m - 1), \dots, -1, 1, \dots, m - 1, m$。 如果$n = 2  m + 1$,则结果为:$-m, -(m - 1), \dots, -1, 0,1, \dots, m - 1, m$。
代码1
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 
 | class Solution {public:
 vector<int> sumZero(int n) {
 vector<int>res;
 if(n & 1 == 1){
 res.push_back(0);
 }
 for(int i = 1; i <= n >> 1; ++i){
 res.push_back(i);
 res.push_back(-i);
 }
 return res;
 }
 };
 
 | 
题目描述
给你 root1 和 root2 这两棵二叉搜索树。 请你返回一个列表,其中包含 两棵树 中的所有整数并按 升序 排序。. 示例 1:  输入:root1 = [2,1,4], root2 = [1,0,3] 输出:[0,1,1,2,3,4] 示例 2: 输入:root1 = [0,-10,10], root2 = [5,1,7,0,2] 输出:[-10,0,0,1,2,5,7,10] 示例 3: 输入:root1 = [], root2 = [5,1,7,0,2] 输出:[0,1,2,5,7] 示例 4: 输入:root1 = [0,-10,10], root2 = [] 输出:[-10,0,10] 示例 5:
 输入:root1 = [2,1,4], root2 = [1,0,3] 输出:[0,1,1,2,3,4] 示例 2: 输入:root1 = [0,-10,10], root2 = [5,1,7,0,2] 输出:[-10,0,0,1,2,5,7,10] 示例 3: 输入:root1 = [], root2 = [5,1,7,0,2] 输出:[0,1,2,5,7] 示例 4: 输入:root1 = [0,-10,10], root2 = [] 输出:[-10,0,10] 示例 5:  输入:root1 = [1,null,8], root2 = [8,1] 输出:[1,1,8,8] 提示: 每棵树最多有 5000 个节点。 每个节点的值在 [-10^5, 10^5] 之间。
 输入:root1 = [1,null,8], root2 = [8,1] 输出:[1,1,8,8] 提示: 每棵树最多有 5000 个节点。 每个节点的值在 [-10^5, 10^5] 之间。
题解1
对于二叉搜索树,中序遍历可以得到有序的序列。分别对两棵二叉搜索树中序遍历,然后再对结果进行归并排序。 但比赛为了求速度,直接将结果用sort排序。
代码1
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 
 | 
 
 
 
 
 
 
 
 
 void inorder(TreeNode* root, vector<int>& res){
 if(root == NULL){
 return;
 }
 inorder(root->left, res);
 res.push_back(root->val);
 inorder(root->right, res);
 }
 class Solution {
 public:
 vector<int> getAllElements(TreeNode* root1, TreeNode* root2) {
 vector<int>res1;
 inorder(root1, res1);
 inorder(root2, res1);
 sort(res1.begin(), res1.end());
 return res1;
 }
 };
 
 | 
题目描述
这里有一个非负整数数组 arr,你最开始位于该数组的起始下标 start 处。当你位于下标 i 处时,你可以跳到 i + arr[i] 或者 i - arr[i]。 请你判断自己是否能够跳到对应元素值为 0 的 任意 下标处。 注意,不管是什么情况下,你都无法跳到数组之外。 示例 1: 输入:arr = [4,2,3,0,3,1,2], start = 5 输出:true 解释: 到达值为 0 的下标 3 有以下可能方案: 下标 5 -> 下标 4 -> 下标 1 -> 下标 3 下标 5 -> 下标 6 -> 下标 4 -> 下标 1 -> 下标 3 示例 2: 输入:arr = [4,2,3,0,3,1,2], start = 0 输出:true 解释: 到达值为 0 的下标 3 有以下可能方案: 下标 0 -> 下标 4 -> 下标 1 -> 下标 3 示例 3 输入:arr = [3,0,2,1,2], start = 2 输出:false 解释:无法到达值为 0 的下标 1 处。 提示: 1 <= arr.length <= 5 * 10^4 0 <= arr[i] < arr.length 0 <= start < arr.length
题解1
BFS,判断能否从起始下标到达值为0的下标位置
代码1
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 
 | class Solution {public:
 bool canReach(vector<int>& arr, int start) {
 vector<int>target;
 int len = arr.size(), frt;
 bool flag = false, res = false;
 vector<int>mark(len, 0);
 vector<int>mark1(len, 0);
 for(int i = 0; i < arr.size(); ++i){
 if(arr[i] == 0){
 mark[i] = 1;
 flag = true;
 }
 }
 if(!flag){
 res = false;
 }
 else{
 
 queue<int>que;
 que.push(start);
 mark1[start] = 1;
 while(!que.empty()){
 frt = que.front();
 que.pop();
 if(mark[frt]){
 res = true;
 break;
 }
 if(frt + arr[frt] < len && !mark1[frt + arr[frt]]){
 que.push(frt + arr[frt]);
 mark1[frt + arr[frt]] = 1;
 }
 if(frt - arr[frt] >= 0 && !mark1[frt - arr[frt]]){
 que.push(frt - arr[frt]);
 mark1[frt - arr[frt]] = 1;
 }
 }
 }
 return res;
 }
 };
 
 | 
题目描述
给你一个方程,左边用 words 表示,右边用 result 表示。 你需要根据以下规则检查方程是否可解: 每个字符都会被解码成一位数字(0 - 9)。 每对不同的字符必须映射到不同的数字。 每个 words[i] 和 result 都会被解码成一个没有前导零的数字。 左侧数字之和(words)等于右侧数字(result)。  如果方程可解,返回 True,否则返回 False。 示例 1: 输入:words = [“SEND”,”MORE”], result = “MONEY” 输出:true 解释:映射 ‘S’-> 9, ‘E’->5, ‘N’->6, ‘D’->7, ‘M’->1, ‘O’->0, ‘R’->8, ‘Y’->’2’ 所以 “SEND” + “MORE” = “MONEY” , 9567 + 1085 = 10652 示例 2: 输入:words = [“SIX”,”SEVEN”,”SEVEN”], result = “TWENTY” 输出:true 解释:映射 ‘S’-> 6, ‘I’->5, ‘X’->0, ‘E’->8, ‘V’->7, ‘N’->2, ‘T’->1, ‘W’->’3’, ‘Y’->4 所以 “SIX” + “SEVEN” + “SEVEN” = “TWENTY” , 650 + 68782 + 68782 = 138214 示例 3: 输入:words = [“THIS”,”IS”,”TOO”], result = “FUNNY” 输出:true 示例 4: 输入:words = [“LEET”,”CODE”], result = “POINT” 输出:false 提示: 2 <= words.length <= 5 1 <= words[i].length, results.length <= 7 words[i], result 只含有大写英文字母 表达式中使用的不同字符数最大为 10
题解1
因为表达式中使用的不同字符数最大为10,字符的取值0-9(值不能相同)最多为$10!$种情况。思路如下: 首先将不重复的字符统计出来,然后用next_permutation产生不同的取值,判断是否符合情况。 这种暴力方式会超时,因为next_permutation产生取值的时间需要o(n)时间,并且包含重复的情况。
代码1
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 
 | bool deal(vector<string>& words, string& result, unordered_map<char, int>& myMap){
 for(int i = 0; i < words.size(); ++i){
 if(words[i].size() > 1 && myMap[words[i][0]] == 0){
 return false;
 }
 }
 if(result.size() > 1 && myMap[result[0]] == 0){
 return false;
 }
 int lSum = 0, rSum = 0, num = 0;
 for(auto word:words){
 num = 0;
 for(auto ch:word){
 num = num * 10 + myMap[ch];
 }
 lSum += num;
 }
 for(auto ch:result){
 rSum = rSum * 10 + myMap[ch];
 }
 return lSum == rSum;
 }
 class Solution {
 public:
 bool isSolvable(vector<string>& words, string result) {
 int len;
 unordered_map<char, int>myMap;
 string str;
 int flag = false;
 int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
 for(auto word:words){
 for(auto ch:word){
 if(myMap.find(ch) == myMap.end()){
 str.push_back(ch);
 myMap[ch] = 0;
 }
 }
 }
 len = str.size();
 do{
 for(int i = 0; i < len; ++i){
 myMap[str[i]] = arr[i];
 }
 if(deal(words, result, myMap)){
 flag = true;
 break;
 }
 }while(next_permutation(arr, arr + 10));
 return flag;
 }
 };
 
 | 
题解2
用dfs来代替next_permutation,不会产生重复的情况。加入前导0的标记并将map换成数组。
代码2
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 
 | vector<int>myMap(26, 0);vector<bool>mark(26, 0);
 string str;
 bool res = false;
 
 bool deal(vector<string>& words, string& result){
 int lSum = 0, rSum = 0, num = 0;
 for(auto word:words){
 num = 0;
 for(auto ch:word){
 num = num * 10 + myMap[ch - 'A'];
 }
 lSum += num;
 }
 for(auto ch:result){
 rSum = rSum * 10 + myMap[ch - 'A'];
 }
 return lSum == rSum;
 }
 
 void dfs(vector<string>& words, string& result, int pos, int used){
 if(res){
 return;
 }
 if(pos == str.size()){
 if(deal(words, result)){
 res = true;
 }
 return;
 }
 for(int i = 0; i < 10; ++i){
 if((mark[str[pos] - 'A'] && i == 0)  used >> i & 1) continue;
 myMap[str[pos] - 'A'] = i;
 dfs(words, result, pos + 1, used  1 << i);
 }
 
 }
 
 
 class Solution {
 public:
 bool isSolvable(vector<string>& words, string result) {
 int len;
 myMap.clear();
 str.clear();
 res = false;
 mark.assign(26, 0);
 myMap.assign(26, 0);
 for(auto word:words){
 mark[word[0] - 'A'] = 1;
 for(auto ch:word){
 if(!myMap[ch - 'A']){
 str.push_back(ch);
 myMap[ch - 'A'] = 1;
 }
 }
 }
 mark[result[0] - 'A'] = 1;
 for(auto ch:result){
 if(!myMap[ch - 'A']){
 str.push_back(ch);
 myMap[ch - 'A'] = 1;
 }
 }
 len = str.size();
 dfs(words, result, 0, 0);
 return res;
 }
 };
 
 | 
题解3
参照圈子
代码3
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 
 | vector<char> h;vector<int> base;
 vector<int> coe(26,0);
 vector<bool> not_zero(26,false);
 
 bool dfs (int pos,int used, int sum) {
 if(pos == h.size()) return sum == 0;
 for(int i = 0 ; i < 10 ; i++) {
 if(used>>i & 1) continue;
 if(i==0 && not_zero[h[pos]-'A']) continue;
 if(dfs(pos+1,used  1<<i, sum+i*coe[h[pos]-'A'])) return true;
 }
 return false;
 };
 
 
 class Solution {
 public:
 bool isSolvable(vector<string>& words, string result) {
 
 h.clear();
 base.clear();
 coe.assign(26, 0);
 not_zero.assign(26, false);
 words.push_back(result);
 base.push_back(1);
 for(int i = 1 ; i <= 8 ; i++) base.push_back(base.back()*10);
 
 for(int j = 0 ; j < words.size() ; j++) {
 string x = words[j];
 for(int i = 0 ; i < x.size() ; i++) {
 if(i==0) not_zero[x[i]-'A'] = true;
 h.push_back(x[i]);
 int flag = j==words.size()-1?-1:1;
 coe[x[i]-'A'] += flag * base[x.size()-1-i];
 }
 }
 sort(h.begin(),h.end());
 h.erase(unique(h.begin(),h.end()),h.end());
 return dfs(0,0,0);
 }
 };
 
 |