#include <iostream>
#include <time.h>
#include <vector>
#include <list>
#include <map>
#include <unordered_map>
#include <algorithm>
#include <stack>
#include <queue>
#include <unordered_set>
#include <math.h>
using namespace std;
struct ListNode
{
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
ListNode(int x,ListNode* p) : val(x), next(p) {}
};
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};
//leetcode 138 复制随机指针链表
class Node {
public:
int val;
Node* next;
Node* random;
Node(int _val) {
val = _val;
next = NULL;
random = NULL;
}
};
//leetcode 133
class NodeGraph {
public:
int val;
vector<NodeGraph*> neighbors;
NodeGraph() {
val = 0;
neighbors = vector<NodeGraph*>();
}
NodeGraph(int _val) {
val = _val;
neighbors = vector<NodeGraph*>();
}
NodeGraph(int _val, vector<NodeGraph*> _neighbors) {
val = _val;
neighbors = _neighbors;
}
};
//1229 leetcode 116
class NodeTwo {
public:
int val;
NodeTwo* left;
NodeTwo* right;
NodeTwo* next;
NodeTwo() : val(0), left(NULL), right(NULL), next(NULL) {}
NodeTwo(int _val) : val(_val), left(NULL), right(NULL), next(NULL) {}
NodeTwo(int _val, NodeTwo* _left, NodeTwo* _right, NodeTwo* _next)
: val(_val), left(_left), right(_right), next(_next) {}
};
int* pAll = new int(11);
class Solution
{
public:
//1218 非递归解法前序遍历
vector<int> preorderTraversal(TreeNode* root) {
vector<int> res;
if(root == NULL) return res;
stack<TreeNode*> s;
TreeNode* p = root;
while (!s.empty() || p)
{
while (p)
{
//cout<<"cur val is "<<p->val<<endl;
res.push_back(p->val);
s.push(p);
p = p->left;
}
if(!s.empty())
{
TreeNode* tmp = s.top();
s.pop();
p = tmp->right;
}
}
return res;
}
vector<int> middleTravel(TreeNode* root)
{
vector<int> res;
if(root == NULL) return res;
stack<TreeNode*> s;
TreeNode* p = root;
while (!s.empty() || p != NULL)
{
while (p != NULL)
{
s.push(p);
p = p->left;
}
if(!s.empty())
{
TreeNode* tmp = s.top();
s.pop();
res.push_back(tmp->val);
p = tmp->right;
}
}
return res;
}
//1218 二叉树层序遍历
vector<vector<int>> travelTreeNodeByFloor(TreeNode* root)
{
vector<vector<int>> res;
if(root == NULL) return res;
queue<TreeNode*> q;
q.push(root);
while (!q.empty())
{
int size = q.size();
int count = 0;
vector<int> curFloor;
while (count < size)
{
TreeNode* curTreeNode = q.front();
q.pop();
curFloor.push_back(curTreeNode->val);
count++;
if(curTreeNode->left != NULL) q.push(curTreeNode->left);
if(curTreeNode->right != NULL) q.push(curTreeNode->right);
}
for_each(curFloor.begin(),curFloor.end(),[](auto& x){cout<<x<<" ";});
cout<<endl;
res.push_back(curFloor);
}
return res;
}
//1221 leetcode 143
void reorderList(ListNode* head) {
if(!head) return;
vector<ListNode*> l;
ListNode* dummyHead = head;
while(dummyHead){
l.push_back(dummyHead);
dummyHead = dummyHead->next;
}
int left = 0, right = l.size()-1;
while(left < right){
l[left]->next = l[right];
l[right--]->next = l[++left];
}
if(left==right || left > right)
l[left]->next = nullptr;
}
//1221 tmp
void travelListNode(ListNode* root)
{
if(root == NULL) return;
cout<<"cur val is "<<root->val<<endl;
travelListNode(root->next);
}
//1214 临时加一个 链表快速排序
//尾插法创建链表 2 3 1 9 8 10
ListNode* headInsertListNode()
{
vector<int> nums = {1,2,3,4};
ListNode* dumy = new ListNode(0); //先建一个首节点,方便后续尾插法插入数据
ListNode* cur = dumy;
for(int i = 0;i<nums.size();i++)
{
ListNode* tmp = new ListNode(nums[i]);
cur->next = tmp;
tmp->next = NULL;
cur = tmp;
}
return dumy->next;
}
void test(int *p)
{
cout<<"before *p is "<<*p<<endl;
int* p1 = new int(12);
p = p1;
cout<<"*p1 is "<<*p1<<endl;
p = pAll;
cout<<"after *p is "<<*p<<endl;
}
//1222 链表非递归反转
ListNode* reverseListNode(ListNode* head)
{
if(head == NULL || (head != NULL && head->next == NULL)) return head;
ListNode* dummy = new ListNode(0);
ListNode* pre = dummy;
ListNode* cur = NULL;
while (head)
{
ListNode* tmp = head;
head = head->next; //head 应该放在前面,不然放后面就退出了
pre->next = tmp;
tmp->next = cur;
cur = tmp;
}
return dummy->next;
}
//1222 leetcode 139
bool wordBreak(string s, vector<string>& wordDict) {
int len = s.size();
unordered_set<string> words(wordDict.begin(),wordDict.end());
vector<bool> dp(len+1,false);
dp[0] = true;
for(int i=1;i<=len;i++)
{
for(int j=0;j<i;j++)
{
if(dp[j] && words.find(s.substr(j,i-j)) != words.end())
{
dp[i] = true;
break;
}
}
}
return dp[len];
/*
vector<vector<bool>> isTure(len+1,vector<bool>(len+1,false));
for(int i=1;i<=len;i++)
{
for(int j= i;j<=len;j++)
{
cout<<s.substr(i-1,j-(i-1))<<" ";
if(words.find(s.substr(i-1,j-(i-1))) != words.end())
{
isTure[i][j] = true;
}
}
cout<<endl;
}
*/
return true;
}
//1222 leetcode 140
/*
给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,在字符串中增加空格来构建一个句子,使得句子中所有的单词都在词典中。返回所有这些可能的句子。
说明:
分隔时可以重复使用字典中的单词。
你可以假设字典中没有重复的单词。
示例 1:
输入:
s = "catsanddog"
wordDict = ["cat", "cats", "and", "sand", "dog"]
输出:
[
"cats and dog",
"cat sand dog"
]
*/
vector<string> wordBreak_2(string s, vector<string>& wordDict) {
//暂时不会 先不写
}
//1222 leetcode 141
bool hasCycle(ListNode *head)
{
ListNode* fast = head, *slow = head;
if(!head) return false;
while(fast && fast->next)
{
fast = fast->next->next;
slow = slow->next;
if(fast == slow)
{
return true;
}
}
return false;
}
//1222 leetcode 142
ListNode *detectCycle(ListNode *head) {
ListNode* fast = head, *slow = head;
if(!head || (head != NULL && head->next == NULL)) return NULL; //单个节点需要考虑
while(fast && fast->next)
{
fast = fast->next->next;
slow = slow->next;
if(fast == slow)
{
break;
}
}
if(fast == slow)
{
ListNode* newHead = head;
while(newHead != fast)
{
newHead = newHead->next; //第二次跑要一个指针从头开始,这个是有原理的,先记一下
fast = fast->next;
}
return newHead;
}
return NULL;
}
//12223 leetcode 138
Node* copyRandomList(Node* head) {
if(head == NULL) return NULL;
vector<int> nums;
map<int,Node*> mp;
map<Node*,int> oldList;
//尾插法建立新的链表
Node* dummy = new Node(0);
Node* pre = dummy;
Node* cur = NULL;
int i = 0;
Node* head1 = head;
Node* head2 = head;
while (head1)
{
Node* tmp = new Node(head1->val);
oldList[head1] = i;
mp[i] = tmp;
i++;
pre->next = tmp;
tmp->next = cur;
pre = tmp;
head1 = head1->next;
}
while (head2)
{
Node* tmp = head2->random;
if(tmp == NULL) nums.push_back(-1);
else
{
nums.push_back(oldList[tmp]);
}
head2 = head2->next;
}
Node* newHead = dummy->next;
i = 0;
while (newHead)
{
if(nums[i] == -1) newHead->random = NULL;
else
{
newHead->random = mp[nums[i]];
}
newHead = newHead->next;
i++;
}
return dummy->next;
}
//1223 leetcode 137
int singleNumber(vector<int>& nums) {
//已完成
}
//1223 leetcode 136已完成
//1223 leetcode 135
int candy(vector<int>& ratings) {
if(ratings.size() == 0) return 0;
vector<int> nums(ratings.size(),0);
nums[0] = 1;
//先从前往后 再从后往前
//从前往后
for(int i =1;i<ratings.size();i++)
{
if(ratings[i] > ratings[i-1]) nums[i] = nums[i-1] + 1;
else nums[i] = 1;
}
//再从后往前
for(int i = ratings.size()-1;i>=1;i--)
{
if(ratings[i-1] > ratings[i] && nums[i-1] <= nums[i]) nums[i-1] = nums[i]+1;
}
int res = 0;
for(auto num : nums)
{
res +=num;
}
return res;
}
//1223 leetcode 134 加油站
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
int len = gas.size();//一共有多少个加油点
if(len == 0 || cost.size() == 0) return -1;
int count = 0;
int pos = 0;
int sum = 0;
for(int i =0;i<len;i++)
{
sum = 0;
count = 0;
for(int j =i;j<len;j++)
{
count++;
sum = sum + gas[j];
sum = sum - cost[j];
if(count == len && sum >= 0) return i;
if(sum < 0) break;
if(j == len-1) j = -1; //下一次从0开始
}
if(sum < 0) continue;
}
return -1;
}
//1224 leetcode 133
NodeGraph* cloneGraph(NodeGraph* node) {
// 这个不会 参考自 https://blog.csdn.net/Bendaai/article/details/80985328?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.control
//后续学习下bfs和dfs专题
map<int,NodeGraph*> mp;
NodeGraph* p = new NodeGraph(node->val);
mp[node->val] = p;
for(auto & x: node->neighbors)
{
if(mp.find(x->val) == mp.end()) p->neighbors.push_back(cloneGraph(x));
else p->neighbors.push_back(mp[x->val]);
}
return p;
}
void travelGraphWithoutDirection(NodeGraph* node)
{
/*
NodeGraph* node1 = new NodeGraph(1);
NodeGraph* node2 = new NodeGraph(2);
NodeGraph* node3 = new NodeGraph(3);
NodeGraph* node4 = new NodeGraph(4);
node1->neighbors.push_back(node2);
node1->neighbors.push_back(node4);
node2->neighbors.push_back(node1);
node2->neighbors.push_back(node3);
node3->neighbors.push_back(node2);
node3->neighbors.push_back(node4);
node4->neighbors.push_back(node1);
node4->neighbors.push_back(node3);
NodeGraph* root = node1;
*/
}
//1224 leetcode 131
vector<vector<string>> res_131;
vector<string> tmp_131;
vector<vector<string>> partition(string s) {
if(s.size() == 0) return res_131;
helper(s,0,s.size()-1);
return res_131;
}
void helper(string s,int begin,int end)
{
if(begin > end)
{
res_131.push_back(tmp_131);
return;
}
for(int i =1;i<= end - begin + 1; i++)
{
if(isPalind(s.substr(begin,i)))
{
cout<<"This s.sub is "<<s.substr(begin,i)<<endl;
tmp_131.push_back(s.substr(begin,i));
helper(s,begin+i,end);
tmp_131.pop_back(); //删除后用于下一次的循环
}
}
}
bool isPalind(string str)
{
if(str.size() == 1) return true;
string str1 = str;
std::reverse(str.begin(),str.end());
return str == str1 ? true : false;
}
//1228 leetcode 130
/*
vector<char> v1 = {'X','X','X','X'};
vector<char> v2 = {'X','O','O','X'};
vector<char> v3 = {'X','X','O','X'};
vector<char> v4 = {'X','O','X','X'};
vector<vector<char>> areas;
areas.push_back(v1);
areas.push_back(v2);
areas.push_back(v3);
areas.push_back(v4);
solution.solve(areas);
cout<<"Final res is : "<<endl;
for(int i=0;i<areas.size();i++)
{
for_each(areas[i].begin(),areas[i].end(),[](auto& x){cout<<x<<" ";});
cout<<endl;
}
*/
void solve(vector<vector<char>>& board) {
if(board.size() == 0) return;
int row = 0, column = 0;
row = board.size();
column = board[0].size();
for(int i=0;i<row;i++)
{
helperSolve(board,i,0);
helperSolve(board,i,column-1);
}
for(int i=1;i<column-1;i++)
{
helperSolve(board,0,i);
helperSolve(board,row-1,i);
}
cout<<"In function "<<endl;
for(int i=0;i<board.size();i++)
{
for_each(board[i].begin(),board[i].end(),[](auto& x){cout<<x<<" ";});
cout<<endl;
}
for(int i=0;i<row;i++)
{
for(int j=0;j<column;j++)
{
if(board[i][j] == 'A') board[i][j] = 'O';
else if(board[i][j] == 'O') board[i][j] = 'X';
}
}
}
void helperSolve(vector<vector<char>>& board,int x,int y)
{
if(x < 0 || x >= board.size() || y >= board[0].size() || y < 0 || board[x][y] != 'O') return;
board[x][y] = 'A';
helperSolve(board,x+1,y);
helperSolve(board,x-1,y);
helperSolve(board,x,y+1);
helperSolve(board,x,y-1);
}
//1228 leetcode 129
/*
TreeNode* l4 = new TreeNode(4);
TreeNode* l5 = new TreeNode(5);
TreeNode* l6 = new TreeNode(6);
TreeNode* l7 = new TreeNode(7);
TreeNode* l2 = new TreeNode(2,l4,l5);
TreeNode* l3 = new TreeNode(3,l6,l7);
TreeNode* l1 = new TreeNode(1,l2,l3);
TreeNode* root = l1;
solution.travelTreeNodeByFloor(root);
cout<<"res is "<<endl;
vector<vector<int>> res = solution.getAllTreeNodePath(root);
for(int i=0;i<res.size();i++)
{
for_each(res[i].begin(),res[i].end(),[](auto& x){cout<<x<<" ";});
cout<<endl;
}
*/
int sumNumbers(TreeNode* root) {
if(root == NULL) return 0;
vector<vector<int>> res;
vector<int> tmp;
helperGetAllPath(root,res,tmp);
int sum = 0;
for(int i =0;i<res.size();i++)
{
int curSum = 0;
for(int j =0;j<res[i].size();j++)
{
curSum = curSum * 10 + res[i][j];
}
sum = sum + curSum;
}
return sum;
}
//1228 tmp 求二叉树根节点到叶子结点所有的路径
vector<vector<int>> getAllTreeNodePath(TreeNode* root)
{
vector<vector<int>> res;
if(root == NULL) return res;
vector<int> tmp;
helperGetAllPath(root,res,tmp);
return res;
}
void helperGetAllPath(TreeNode* root, vector<vector<int>>& res,vector<int> tmp)
{
if(root == NULL) return;
if(root != NULL) tmp.push_back(root->val);
if(root != NULL && root->left == NULL && root->right == NULL)
{
res.push_back(tmp);
}
helperGetAllPath(root->left,res,tmp);
helperGetAllPath(root->right,res,tmp);
}
//1228 leetcode 125
bool isPalindromeNew(string s) {
if(s.size() == 0) return true;
string s1;
for(int i =0;i<s.size();i++)
{
if((s[i] >= '0' && s[i] <= '9') || (s[i] >= 'a' && s[i] <= 'z') || (s[i] >= 'A' && s[i] <= 'Z'))
s1.push_back(s[i]);
}
string s2 = s1;
std::reverse(s2.begin(),s2.end());
cout<<"s1 is "<<s1<<" s2 is "<<s2<<endl;
for(int i=0;i<s1.size();i++)
{
if(((s1[i] >= 'a' && s1[i] <= 'z') || (s1[i] >= 'A' && s1[i] <= 'Z')) && (s1[i] - s2[i] != 32) && (s1[i]-s2[i] != -32) && (s1[i] != s2[i]))
return false;
if((s1[i] >= '0' && s1[i] <= '9') && (s1[i] != s2[i])) return false;
}
//cout<<'A' - 'a'<<endl;
return true;
}
//1228 leetcode 128
int longestConsecutive(vector<int>& nums) {
if(nums.size() == 0) return 0;
vector<int> newNums = nums;
std::sort(newNums.begin(),newNums.end());
vector<int> unSameNums; //防止有重复的值
int i = 0;
for(i =0;i<newNums.size();i++)
{
while((i+1 < newNums.size()) && (newNums[i] == newNums[i+1]))
{
i++;
}
unSameNums.push_back(newNums[i]);
}
int len = unSameNums.size();
int res = 1;
i = 0;
while (i < len)
{
int tmpCount = 0;
while ((i+1 < len) && (unSameNums[i] + 1 == unSameNums[i+1]))
{
tmpCount++;
i++;
}
res = max(tmpCount+1,res);
i++;
}
return res;
}
//1229 leetcode 127
int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
//先不做
}
//1229 leetcode 120
//这个不会 参考自官方题解
int minimumTotal(vector<vector<int>>& triangle) {
if(triangle.size() == 0) return 0;
int len = triangle.size();
vector<vector<int>> dp(len,vector<int>(len,0));
dp[0][0] = triangle[0][0];
for(int i=1;i<len;i++)
{
for(int j=0;j<=i;j++)
{
if(j == 0)
{
dp[i][j] = dp[i-1][j] + triangle[i][j];
}
else if(j == i)
{
dp[i][j] = dp[i-1][j-1] + triangle[i][j];
}
else
{
dp[i][j] = min(dp[i-1][j-1],dp[i-1][j]) + triangle[i][j];
}
}
}
auto p = min_element(dp[len-1].begin(),dp[len-1].end());
return *p;
}
//1229 leetcode 118
vector<vector<int>> generate(int numRows) {
vector<vector<int>> res;
if(numRows <= 0) return res;
vector<int> v1 = {1};
res.push_back(v1);
if(numRows == 1) return res;
vector<int> v2 = {1,1};
res.push_back(v2);
if(numRows == 2) return res;
for(int i=2;i<numRows;i++)
{
vector<int> tmp(i+1,0);
for(int j=0;j<=i;j++)
{
if(j == 0 || j == i) tmp[j] = 1;
else
{
tmp[j] = res[i-1][j] + res[i-1][j-1];
}
}
res.push_back(tmp);
}
return res;
}
//1229 leetcode 119
vector<int> getRow(int rowIndex) {
//参考118 已完成
}
//1229 leetcode 112
bool hasPathSum(TreeNode* root, int sum) {
if(root == NULL) return false;
vector<vector<int>> allPathRes;
vector<int> tmp;
helperGetAllPathSum(root,allPathRes,tmp);
for(int i =0;i<allPathRes.size();i++)
{
int curSum = 0;
for(int j=0;j<allPathRes[i].size();j++)
{
curSum +=allPathRes[i][j];
}
if(curSum == sum)
{
return true;
}
}
return false;
}
//1229 leetcode 113
vector<vector<int>> pathSum(TreeNode* root, int sum) {
vector<vector<int>> res;
if(root == NULL) return res;
vector<vector<int>> allPathRes;
vector<int> tmp;
helperGetAllPathSum(root,allPathRes,tmp);
for(int i =0;i<allPathRes.size();i++)
{
int curSum = 0;
for(int j=0;j<allPathRes[i].size();j++)
{
curSum +=allPathRes[i][j];
}
if(curSum == sum) res.push_back(allPathRes[i]);
}
return res;
}
void helperGetAllPathSum(TreeNode* root,vector<vector<int>>& res,vector<int> cur)
{
if(root == NULL) return;
cur.push_back(root->val);
if(root != NULL && root->left == NULL && root->right == NULL)
{
res.push_back(cur);
}
helperGetAllPathSum(root->left,res,cur);
helperGetAllPathSum(root->right,res,cur);
}
//1229 leetcode 114
void flatten(TreeNode* root) {
if(root == NULL) return;
vector<TreeNode*> preOrderRes = preOrderTreeNode(root);
for(int i=0;i<preOrderRes.size();i++)
{
cout<<preOrderRes[i]->val<<" ";
}
cout<<endl;
for(int i=0;i<preOrderRes.size()-1;i++)
{
preOrderRes[i]->left = NULL;
preOrderRes[i]->right = preOrderRes[i+1];
}
preOrderRes[preOrderRes.size()-1]->left = NULL;
preOrderRes[preOrderRes.size()-1]->right = NULL;
cout<<"cur Finish"<<endl;
}
vector<TreeNode*> preOrderTreeNode(TreeNode* root)
{
vector<TreeNode*> res;
if(root == NULL) return res;
res.push_back(root);
vector<TreeNode*> leftNodes = preOrderTreeNode(root->left);
vector<TreeNode*> rightNodes = preOrderTreeNode(root->right);
for(int i=0;i<leftNodes.size();i++)
{
res.push_back(leftNodes[i]);
}
for(int i =0;i<rightNodes.size();i++)
{
res.push_back(rightNodes[i]);
}
return res;
}
//1229 leetcode 115
int numDistinct(string s, string t) {
//这个不会
if(s.size() == 0 || t.size() == 0) return 0;
int tLen = t.size(), sLen = s.size();
//int型会溢出 需要使用long long
vector<vector<long long>> dp(tLen+1, vector<long long>(sLen+1,0)); //dp[i][j] 代表 T 前 i 字符串可以由 S j 字符串组成最多个数.
for(int i=0;i<=sLen;i++)
{
dp[0][i] = 1;
}
//string s = "babgbag";
//string t = "bag";
for(int i=1;i<=tLen;i++)
{
for(int j=1;j<=sLen;j++)
{
if(s[j-1] == t[i-1]) dp[i][j] = dp[i-1][j-1] + dp[i][j-1];
else dp[i][j] = dp[i][j-1];
}
}
cout<<"dp raise : "<<endl;
for(int i =0;i<dp.size();i++)
{
for_each(dp[i].begin(),dp[i].end(),[](auto& x){cout<<x<<" ";});
cout<<endl;
}
return dp[tLen][sLen];
}
//1229 leetcode 116
NodeTwo* connect(NodeTwo* root)
{
if(root == NULL) return NULL;
queue<NodeTwo*> q;
vector<vector<NodeTwo*>> allFloorNodes;
q.push(root);
while (!q.empty())
{
int qSize = q.size();
int count = 0;
vector<NodeTwo*> cur;
while (count < qSize)
{
NodeTwo* tmp = q.front();
q.pop();
count++;
cur.push_back(tmp);
if(tmp->left != NULL) q.push(tmp->left);
if(tmp->right != NULL) q.push(tmp->right);
}
allFloorNodes.push_back(cur);
}
for(int i=0;i<allFloorNodes.size();i++)
{
for(int j=0;j<allFloorNodes[i].size()-1;j++)
{
allFloorNodes[i][j]->next = allFloorNodes[i][j+1];
}
allFloorNodes[i][allFloorNodes[i].size()-1]->next = NULL;
}
return root;
}
//1230 leet117
Node* connect_Leetcode117(Node* root)
{
//已完成
}
//1230 leetcode 111
int minDepth(TreeNode* root) {
if(root == NULL) return 0;
if(root->left == NULL) return 1 + minDepth(root->right);
if(root->right == NULL) return 1 + minDepth(root->left);
return 1 + min(minDepth(root->right),minDepth(root->left));
}
//1229 leetcode 104
int treeNodeDepth(TreeNode* root)
{
if(root == NULL) return 0;
if(root->left == NULL && root->right == NULL) return 1;
return 1 + max(treeNodeDepth(root->left),treeNodeDepth(root->right));
}
//1230 leetcode 109 有序链表转换二叉搜索树
TreeNode* sortedListToBST(ListNode* head) {
if(head == NULL) return NULL;
vector<int> nums;
while (head)
{
nums.push_back(head->val);
head = head->next;
}
TreeNode* newRoot = helpRebuildTreeNodeByListNodes(nums,0,nums.size()-1);
return newRoot;
}
TreeNode* helpRebuildTreeNodeByListNodes(vector<int>& nums,int begin,int end)
{
if(begin > end) return NULL;
int mid = (begin + end)/2;
TreeNode* root = new TreeNode(nums[mid]);
root->left = helpRebuildTreeNodeByListNodes(nums,begin,mid-1);
root->right = helpRebuildTreeNodeByListNodes(nums,mid+1,end);
return root;
}
//1230 leetcode 107
vector<vector<int>> levelOrderBottom(TreeNode* root) {
vector<vector<int>> res;
if(root == NULL) return res;
queue<TreeNode*> q;
q.push(root);
while (!q.empty())
{
int qSize = q.size();
int count = 0;
vector<int> cur;
while (count < qSize)
{
TreeNode* tmp = q.front();
q.pop();
count++;
cur.push_back(tmp->val);
if(tmp->left != NULL) q.push(tmp->left);
if(tmp->right != NULL) q.push(tmp->right);
}
res.push_back(cur);
}
std::reverse(res.begin(),res.end());
return res;
}
//1230 leetcode 106
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
//这个不会
}
TreeNode* rebuildTreeByMidAndPost(vector<int>& inorder, vector<int>& postorder,int midBegin,int midEnd,int postBegin,int postEnd)
{
}
//210104 leetcode 105
TreeNode* buildTreeByPreAndMid(vector<int>& preorder, vector<int>& inorder) {
if(preorder.size() == 0 || inorder.size() == 0) return NULL;
int len = preorder.size();
TreeNode* res = helpRebuild(0,len-1,0,len-1,preorder,inorder);
return res;
}
TreeNode* helpRebuild(int leftPre,int rightPre,int leftIn,int rightIn,vector<int>& pre, vector<int>& in)
{
if(leftPre > rightPre || leftIn > rightIn) return NULL;
TreeNode* root = new TreeNode(pre[leftPre]);
int rootIn = leftIn;
while(rootIn <= rightIn && in[rootIn] != pre[leftPre]) rootIn++;
int left = rootIn - leftIn;
root->left = helpRebuild(leftPre+1,leftPre+3,leftIn,rootIn-1,pre,in);
root->right = helpRebuild(leftPre+1+left,rightPre,rootIn+1,rightIn,pre,in);
return root;
}
//21_0104 leetcode 67
string addBinary(string a, string b) {
if(a.size() == 0 && b.size() == 0) return "";
if(a.size() == 0) return b;
if(b.size() == 0) return a;
std::reverse(a.begin(),a.end());
std::reverse(b.begin(),b.end());
long long num1 = (long long)atoi(a.c_str());
long long num2 = (long long)atoi(b.c_str());
int lenA = a.size();
int lenB = b.size();
int i = 0;
int cur = 0;//这个表示进位
vector<int> nums;
for(i=0;i<lenA || i <lenB;i++)
{
if(i >= lenA && i < lenB)
{
int val = 0;
int tmp = cur + (b[i] - '0');
if(tmp >= 2)
{
val = tmp-2;
tmp = 1;
}
else
{
val = tmp;
cur = 0;
}
nums.push_back(val);
}
else if (i < lenA && i >= lenB)
{
int val = 0;
int tmp = cur + (a[i] - '0');
if(tmp >= 2)
{
val = tmp-2;
cur = 1;
}
else
{
val = tmp;
cur = 0;
}
nums.push_back(val);
}
else
{
int val = 0;
int tmp = cur + (a[i] - '0') + (b[i] - '0');
if(tmp >= 2)
{
val = tmp-2;
cur = 1;
}
else
{
val = tmp;
cur = 0;
}
nums.push_back(val);
}
}
if(cur == 1) nums.push_back(cur); //最后一位进位
for_each(nums.begin(),nums.end(),[](auto& x){cout<<x<<" ";});
cout<<endl;
string res = "";
for(i=nums.size()-1;i>=0;i--)
{
res = res + to_string(nums[i]);
}
return res;
}
//21_0105 leetcode 98
bool isValidBST(TreeNode* root) {
//已完成
//判断是否是二叉树 只要判断中序遍历是否是升序即可
if(root == NULL) return true;
vector<int> midTravelRes = getMidTravelTreeNode(root);
for_each(midTravelRes.begin(),midTravelRes.end(),[](auto& x){cout<<x<<" ";});
cout<<endl;
for(int i=0;i<midTravelRes.size()-1;i++)
{
if(midTravelRes[i] >= midTravelRes[i+1]) return false;
}
return true;
}
vector<int> getMidTravelTreeNode(TreeNode* root)
{
vector<int> res;
if(root == NULL) return res;
vector<int> leftRes;
vector<int> rightRes;
leftRes = getMidTravelTreeNode(root->left);
rightRes = getMidTravelTreeNode(root->right);
for(int i=0;i<leftRes.size();i++) res.push_back(leftRes[i]);
res.push_back(root->val);
for(int i=0;i<rightRes.size();i++) res.push_back(rightRes[i]);
return res;
}
//21_0105 leetcode 99
void recoverTree(TreeNode* root) {
if(root == NULL) return;
vector<TreeNode*> midTravelRes = getMidTravelTreeNodes(root);
TreeNode* firstNode = NULL, *secondNode = NULL;
vector<int> actualNums;
for(int i=0;i<midTravelRes.size();i++)
{
cout<<midTravelRes[i]->val<<" ";
actualNums.push_back(midTravelRes[i]->val);
}
cout<<endl;
std::sort(actualNums.begin(),actualNums.end());
for_each(actualNums.begin(),actualNums.end(),[](auto& x){cout<<x<<" ";});
cout<<endl;
for(int i=0;i<midTravelRes.size();i++)
{
if(midTravelRes[i]->val != actualNums[i])
{
if(firstNode == NULL) firstNode = midTravelRes[i];
else
{
secondNode = midTravelRes[i];
break;
}
}
}
if(firstNode && secondNode)
{
int tmp = firstNode->val;
firstNode->val = secondNode->val;
secondNode->val = tmp;
}
}
vector<TreeNode*> getMidTravelTreeNodes(TreeNode* root)
{
vector<TreeNode*> res;
if(root == NULL) return res;
vector<TreeNode*> leftRes;
vector<TreeNode*> rightRes;
leftRes = getMidTravelTreeNodes(root->left);
rightRes = getMidTravelTreeNodes(root->right);
for(int i=0;i<leftRes.size();i++) res.push_back(leftRes[i]);
res.push_back(root);
for(int i=0;i<rightRes.size();i++) res.push_back(rightRes[i]);
return res;
}
//21_0105 leetcode 96
int numTrees(int n) {
if(n == 0 || n == 1) return 1;
if(n == 2) return 2;
int res = 0;
for(int i=1;i<=n;i++)
{
if(i == 1 || i == n) res = res + numTrees(n-1);
else
{
int before = i-1;
int after = n-i;
res = res + (numTrees(before) * numTrees(after));
}
}
return res;
}
//21_0105 leetcode 95
vector<TreeNode*> generateTrees(int n) {
//已完成
}
//leetcode 93 评论区参考答案
vector<string> restoreString2(string s) {
string temp;
dfs2(s,temp,0);
return res_Leetcode93;
}
void dfs2(string s, string& temp, int word_num){
cout<<"cur begin s si "<<s<<endl;
if(word_num == 4){
cout<<"dfs2 s.size is "<<s.size()<<endl;
if(s.empty()) res_Leetcode93.push_back(temp);
return;
}
else{
if(word_num > 0) temp += '.';
for(int i = 1; i <= 3 && i <= s.length(); ++i){
if(valid2(s.substr(0,i))){
cout<<"restore2 s.substr is "<<s.substr(0,i)<<" temp is "<<temp<<endl;
temp += s.substr(0,i);
dfs2(s.substr(i,s.length()-i),temp,word_num+1);
cout<<"erase tmp.lengh is "<<temp.substr(temp.length()-i,i)<<endl;
temp.erase(temp.length()-i,i);
}
}
temp.pop_back();
}
}
bool valid2(const string& s){
if(s.empty() || (s[0] == '0' && s.size()>1) ) return false;
int val = stoi(s);
if(val >= 0 && val <= 255) return true;
return false;
}
//21_0106 leetcode 93
vector<string> res_Leetcode93;
vector<string> restoreIpAddresses(string s) {
// 这个不会,参考自leetcode 评论区 很有意思的一道题
if(s.size() < 4 || s.size() >12) return res_Leetcode93;
string cur = "";
helpDfsRestoreIpAddress(s,cur,0);
return res_Leetcode93;
}
void helpDfsRestoreIpAddress(string s,string& tmp,int count)
{
cout<<"begin s si "<<s<<endl;
if(count == 4)
{
if(s.empty())
{
res_Leetcode93.push_back(tmp);
return;
}
}
else
{
if(count > 0) tmp = tmp + ".";
for(int i=1;i<=3 && i<=s.size();i++)
{
if(validString(s.substr(0,i)))
{
cout<<"This substri is "<<s.substr(0,i)<<" This tmp is "<<tmp<<endl;
tmp = tmp + s.substr(0,i);
helpDfsRestoreIpAddress(s.substr(i,s.size()-i),tmp,count+1);
cout<<"tmp erase is "<<tmp.substr(tmp.size()-1,i)<<endl;
tmp.erase(tmp.size()-i,i); //这个是做什么的
}
}
cout<<"before pop_back tmp is "<<tmp<<endl;
tmp.pop_back(); //看下这个啥意思
}
}
bool validString(string str)
{
if(str.size() > 3 || str.size() == 0) return false;
if(str[0] == '0' && str.size()>1) return false;
int res = atoi(str.c_str());
if(res >=0 && res <= 255) return true;
return false;
}
//21_0106 临时反转链表
//第一种 使用额外空间 直接头插法 尾插法和原来一样,需要使用头插法就是正好是反转的
ListNode* reverseList1(ListNode* head)
{
ListNode* dummy = new ListNode(0);
ListNode* pre = dummy;
ListNode* cur = NULL;
while (head)
{
ListNode* tmp = new ListNode(head->val);
pre->next = tmp;
tmp->next = cur;
cur = tmp;
head = head->next;
}
return dummy->next;
}
//第二种 不使用额外空间,直接一次遍历直接反转,改变原来的结构
ListNode* reverseList2(ListNode* head)
{
/*
//非递归做法
if(head == NULL || head->next == NULL) return head;
ListNode* pre = head;
ListNode* cur = NULL;
while (head)
{
ListNode* nextNode = head->next;
head->next = cur;
cur = head;
head = nextNode;
}
return cur;
*/
//递归解法
if(head == NULL || head->next == NULL) return head;
ListNode* nextNode = head->next;
ListNode* newListHead = reverseList2(nextNode);
ListNode* head2 = head->next;
head2->next = head;
head->next = NULL;
return newListHead;
}
//21_0106 leetcode 92
ListNode* reverseBetween(ListNode* head, int m, int n) {
if(head == NULL || m <= 0 || n <= 0 || head->next == NULL) return head;
//一趟遍历的已经提交通过,目前来试下这个不限制一趟的
int count = 0;
ListNode* head1 = head;
ListNode* newTail = NULL, *newHead = NULL;
ListNode* pre = new ListNode(0);
pre->next = head;
ListNode* lastNode = NULL;
while (head1)
{
count++;
if(count < m) pre = pre->next;
else if(count == m) newTail = head1;
else if(count == n)
{
newHead = head1;
lastNode = head1->next;
break;
}
head1 = head1->next;
}
newHead->next = NULL;
ListNode* reverseNewHead = reverseList2(newTail);
pre->next = reverseNewHead;
newTail->next = lastNode;
return head;
}
//21_0106 leetcode 91
int numDecodings(string s) {
// 这个不会,参考https://leetcode-cn.com/problems/decode-ways/comments/ 搜索"ChengMing"
int cnt = 0;
if(s.size() == 0 || (s.size() >= 1 && s[0] == '0')) return 0;
if(s.size() == 1) return 1;
vector<int> dp(s.size()+1,0);
dp[0] = 1; //"12321"
for(int i=0;i<s.size();i++)
{
dp[i+1] = (s[i] == '0' ? 0 : dp[i]);
if(i > 0 && (s[i-1] == '1' || (s[i-1] == '2' && s[i] <= '6')))
{
dp[i+1] += dp[i-1];
}
}
return dp.back();
}
//21_0107 leetcode 78
vector<vector<int>> res_Leetcode78;
vector<vector<int>> subsets(vector<int>& nums) {
res_Leetcode78.push_back({});
if(nums.size() == 0) return res_Leetcode78;
int len = nums.size();
vector<int> tmp;
dfsHelpSubsets(nums,0,tmp,len);
return res_Leetcode78;
}
void dfsHelpSubsets(vector<int>& nums,int index,vector<int> tmp,int len)
{
if(len == index) return;
tmp.push_back(nums[index]);
res_Leetcode78.push_back(tmp);
dfsHelpSubsets(nums,index+1,tmp,len); //包含当前元素
tmp.pop_back();
dfsHelpSubsets(nums,index+1,tmp,len);
}
//21_0107 leetcode 90
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
res_Leetcode78.push_back({});
if(nums.size() == 0) return res_Leetcode78;
int len = nums.size();
vector<int> tmp;
dfsHelpSubsets_new(nums,0,tmp,len);
return res_Leetcode78;
}
void dfsHelpSubsets_new(vector<int>& nums,int index,vector<int> tmp,int len)
{
bool flag = false;
if(len == index) return;
tmp.push_back(nums[index]);
for(int i =0;i<res_Leetcode78.size();i++)
{
int cnt = 0;
if(tmp.size() != res_Leetcode78[i].size()) continue;
vector<int> v1 = tmp;
std::sort(v1.begin(),v1.end());
vector<int> v2 = res_Leetcode78[i];
std::sort(v2.begin(),v2.end());
for(int j=0;j<v2.size();j++)
{
if(v1[j] != v2[j]) break;
cnt++;
}
if(cnt == tmp.size())
{
flag = true;
break;
}
}
if(true != flag) res_Leetcode78.push_back(tmp);
dfsHelpSubsets_new(nums,index+1,tmp,len); //包含当前元素
tmp.pop_back();
dfsHelpSubsets_new(nums,index+1,tmp,len);
}
//21_0107 leetcode 89
vector<int> grayCode(int n) {
//已完成
}
//21_0107 leetcode 87 //先不做 不会这个
bool isScramble(string s1, string s2) {
if(s1.size() == 0 && s2.size() == 0) return true;
if(s1.size() == 0 || s2.size() == 0 || s1.size() != s2.size()) return false;
}
//21_0107 leetcode 86
/*
ListNode* l6 = new ListNode(2);
ListNode* l5 = new ListNode(5,l6);
ListNode* l4 = new ListNode(2,l5);
ListNode* l3 = new ListNode(3,l4);
ListNode* l2 = new ListNode(4,l3);
ListNode* l1 = new ListNode(1,l2);
ListNode* head = l1;
solution.travelListNode(head);
cout<<"after change "<<endl;
ListNode* res = solution.partition(head,3);
solution.travelListNode(res);
*/
ListNode* partition(ListNode* head, int x) {
if(head == NULL) return NULL;
vector<int> small;
vector<int> big;
ListNode* head1 = head;
while (head1)
{
if(head1->val < x) small.push_back(head1->val);
else big.push_back(head1->val);
head1 = head1->next;
}
ListNode* dummy = new ListNode(0);
ListNode* pre = dummy;
ListNode* cur = NULL;
vector<int> nums;
for(int i=0;i<small.size();i++) nums.push_back(small[i]);
for(int i=0;i<big.size();i++) nums.push_back(big[i]);
for(int i=0;i<nums.size();i++)
{
ListNode* tmp = new ListNode(nums[i]);
cur = tmp;
pre->next = cur;
pre = cur;
cur = NULL;
}
head = dummy->next;
return head;
}
//21_0108 leetcode 85
/*
vector<char> v1 = {'1','0','1','0','0'};
vector<char> v2 = {'1','0','1','1','1'};
vector<char> v3 = {'1','1','1','1','1'};
vector<char> v4 = {'1','0','0','1','0'};
vector<vector<char>> matrix;
matrix.push_back(v1);
matrix.push_back(v2);
matrix.push_back(v3);
matrix.push_back(v4);
int res = solution.maximalRectangle(matrix);
//cout<<"res is "<<res<<endl;
*/
int maximalRectangle(vector<vector<char>>& matrix) {
//21_0108 不会 根据提示可以每一层分别转换为柱状图,然后转换为第84题的解法
//参考自 https://leetcode-cn.com/problems/maximal-rectangle/comments/ 搜索"追梦人"
if(matrix.size() == 0) return 0;
vector<vector<int>> areas(matrix.size(),vector<int>(matrix[0].size(),0));
int res = 0;
for(int i=0;i<matrix.size();i++)
{
for(int j=0;j<matrix[i].size();j++)
{
if(i == 0)
{
if(matrix[i][j] == '1') areas[0][j] = 1;
else areas[0][j] = 0;
}
else
{
if(matrix[i][j] == '0') areas[i][j] = 0;
else areas[i][j] = areas[i-1][j] + 1;
}
}
int tmpRes = getCurMaxArea(areas[i]);
res = max(res,tmpRes);
}
return res;
}
//第84道题目算法
int getCurMaxArea(vector<int>& nums)
{
if(nums.size() == 0) return 0;
int maxArea = 0;
int len = nums.size();
for(int i = 0;i<len;i++)
{
if(len * nums[i] <= maxArea) continue;
int left = i-1, right = i+1;
while(left >= 0 && nums[left] >= nums[i]) left--;
while(right < len && nums[right] >= nums[i]) right++;
maxArea = max(maxArea,(right - left - 1) * nums[i]);
}
return maxArea;
}
//21_0108 leetcode 84
int largestRectangleArea(vector<int>& heights) {
if(heights.size() == 0) return 0;
//简单暴力法求解
int res = 0;
int len = heights.size();
for(int i=0;i<heights.size();i++)
{
if(len * heights[i] <= res) continue;
int left = i-1, right = i+1;
while (left >= 0 && heights[left] >= heights[i]) left--;
while (right < len && heights[right] >= heights[i]) right++;
res = max(res,(right - left - 1) * heights[i]);
}
return res;
}
//21_0108 leetcode 82
ListNode* deleteDuplicates(ListNode* head) {
if(head == NULL || head->next == NULL) return head;
ListNode* head1 = head;
vector<int> nums;
vector<int> simplyNums;
while(head1)
{
nums.push_back(head1->val);
head1 = head1->next;
}
for(int i =0;i<nums.size()-1;i++)
{
int j = i;
if(nums[j] != nums[j+1]) simplyNums.push_back(nums[j]);
else
{
while(j < nums.size()-1 && nums[j] == nums[j+1]) j++;
i = j;
}
}
if(nums[nums.size()-1] != nums[nums.size()-2]) simplyNums.push_back(nums[nums.size()-1]);
for_each(simplyNums.begin(),simplyNums.end(),[](auto& x){cout<<x<<" ";});
cout<<endl;
ListNode* dummy = new ListNode(0);
ListNode* pre = dummy;
ListNode* cur = NULL;
for(int i=0;i<simplyNums.size();i++)
{
ListNode* tmp = new ListNode(simplyNums[i]);
cur = tmp;
pre->next = cur;
pre = cur;
cur = NULL;
}
head = dummy->next;
return dummy->next;
}
};
int main()
{
Solution solution;
ListNode* l7 = new ListNode(5);
ListNode* l6 = new ListNode(4,l7);
ListNode* l5 = new ListNode(4,l6);
ListNode* l4 = new ListNode(3,l5);
ListNode* l3 = new ListNode(3,l4);
ListNode* l2 = new ListNode(2,l3);
ListNode* l1 = new ListNode(1,l2);
ListNode* head = l1;
solution.travelListNode(head);
cout<<"after simplty"<<endl;
time_t now_time = time(NULL);
tm* thisLocalTime = localtime(&now_time);
cout<<endl;
cout<<asctime(thisLocalTime)<<endl;
system("pause");
return 0;
}