您的位置:首页 > 其它

【LeetCode121-130】买卖锁,二叉树搜索,回文检测,恶心的wordladder2 BFS, 围棋消除BFS

2017-06-29 13:19 459 查看

121.卖买锁问题【easy】

vector代表第i天买卖锁的价格,要求最大利润(进锁必须再卖锁之前)

只遍历一遍

class Solution {
public:
int maxProfit(vector<int>& prices) {
if(prices.size()<=1)return 0;
int result=0,begin=prices[0];
for(int i=1;i<prices.size();++i){
if(prices[i]<=begin)begin=prices[i];
else result=max(result,prices[i]-begin);
}
return result;
}
};


122.可以多次买卖的问题【easy】

//但必须在下次买进之前卖出。

class Solution {
public:
int maxProfit(vector<int>& prices) {
//必须先买进再卖出
if(prices.size()<=1)return 0;
int profit=0;
for(int i=0;i<prices.size()-1;++i){
if(prices[i]<prices[i+1])profit+=(prices[i+1]-prices[i]);
}
return profit;
}
};

123.买卖锁问题三【hard】

只允许两次买卖

class Solution {
public:
int maxProfit(vector<int>& prices) {
if (prices.size() <= 1)return 0;
vector<int>dp(prices.size(), 0);
vector<int>dp2(prices.size(), 0);
int result = 0, max = prices[0], min = prices[0];
for (int i = 1; i<prices.size(); ++i) {
if (prices[i]<min) { dp[i] = dp[i - 1]; min = prices[i]; max = prices[i]; }//max=prices[i]很重要
else if (prices[i]>max) { max = prices[i]; dp[i] = std::max(dp[i - 1], max - min); }
else dp[i] = dp[i - 1];
}
dp2[0] = dp.back();

for (int i = 1; i<dp2.size(); ++i) {
int pre = 0; max = prices[i]; min = prices[i];
for (int j = i+1; j<prices.size(); ++j) {
if (prices[j]<min) { min = prices[j]; max = prices[j]; }//max=prices[i]很重要
else if (prices[j]>max) { max = prices[j]; pre = std::max(pre, max - min); }
}
dp2[i] = pre;
}

for (int i = 0; i<prices.size() - 1; ++i) {
result = std::max(result, dp[i] + dp2[i + 1]);
}
result = std::max(result, dp2[0]);
return result;
}

};

124.二叉树搜索和最大路径(任意两点或单点)【hard】

用到了迭代……(这里预期的返回值有俩,所以用了vector)

class Solution {
public:
int maxPathSum(TreeNode* root) {
if(!root)return 0;
return help(root)[1];

}
vector<int> help(TreeNode* root){
//0位置代表经过这一点最大多少,1位置代表结果
vector<int>result(2,-2147483648);//防止空子树返回{0,0}干扰……
if(!root)return result;
if(!root->left&&!root->right){
result[0]=result[1]=root->val;
return result;
}
vector<int>a=help(root->left);
vector<int>b=help(root->right);
result[0]=std::max(a[0],b[0]);

if(result[0]>0){result[0]+=root->val;}else result[0]=root->val;
int temp=root->val;
temp+=(a[0]>0)?a[0]:0;
temp+=(b[0]>0)?b[0]:0;
result[1]=max(a[1],max(b[1],temp));
return result;
}

};


125.回文检测【easy】

只看数字和字母,不区分大小写

class Solution {
public:
bool isPalindrome(string s) {
string result="";
for(int i=0;i<s.size();++i){

if(s[i]-'a'>=0&&s[i]-'a'<26)result+=s[i];
else if(s[i]-'A'>=0&&s[i]-'A'<26)result+=(s[i]-'A'+'a');
else if(s[i]-'0'>=0&&s[i]-'0'<10)result+=s[i];
}
return help(result);
}
bool help(string s){
for(int i=0;i<s.size()/2;++i){
if(s[i]!=s[s.size()-1-i])return false;
}
return true;
}
};


126.WordLadder2,耗时最久的一道题!!!!!!

前前后后拖了几周,,,终于做了出来……花了1595ms,击败了0.0%的人。。。真的吓死自己了……

class Solution {
public:
vector<vector<string>> findLadders(string beginWord, string endWord, vector<string>& wordList) {
int Num = wordList.size();
wordList.push_back(beginWord);

int End=-1;
vector<vector<bool>>re(Num, vector<bool>(Num, false));//存储List里单词两两关系,用int超出空间限制
for (int i = 0; i <Num; ++i) {
re[i][i] = 1; if (wordList[i] == endWord)End = i;
for (int j = i+1; j < Num; ++j) {
re[j][i]=re[i][j] = guanxi(wordList[i], wordList[j]);
}
}
vector<int>level(Num, Num + 1);
bool goon = true;
vector<vector<int>>Info;
vector<int>first_;
for (int i = 0; i < Num; ++i) {
if (guanxi(beginWord, wordList[i])) {
level[i] = 1;
first_.push_back(i);
if (i == End)goon = false;
}
}
Info.push_back(first_);
if (first_.size() == 0)return{};
while (goon) {
vector<int>first;
for(int j=0;j<Info.back().size();++j){
for (int i = 0; i < Num; ++i) {
if (re[Info.back()[j]][i]) {
if(level[i]==Num+1){
level[i] = Info.size() + 1;
first.push_back(i);}
if (i == End)goon = false;
}
}
}
if (first.size() == 0)return{};
Info.push_back(first);
}
int Length = Info.size() + 1;
vector<vector<string>>result;
vector<string>temp;
temp.push_back(beginWord);
help(result, Info, level, wordList,0,temp,-1,End,re);
return result;

}
void help(vector<vector<string>>&result, vector<vector<int>>Info,vector<int>level, vector<string>& wordList,int begin,vector<string>&temp,int endlocation,int End, vector<vector<bool>>&re) {
if (begin == Info.size()) {
if (endlocation == End)result.push_back(temp);
return;
}
if (begin == 0) {
for (int i = 0; i < Info[0].size(); ++i) {
temp.push_back(wordList[Info[0][i]]);
help(result, Info, level, wordList, 1, temp, Info[0][i],End,re);
temp.pop_back();
}
}
else {
for (int i = 0; i < Info[begin].size(); ++i) {
if(re[endlocation][Info[begin][i]]){
temp.push_back(wordList[Info[begin][i]]);
help(result, Info, level, wordList, begin+1, temp, Info[begin][i], End,re);
temp.pop_back();
}
}
}
}

bool guanxi(string a, string b) {
int temp = 2;
for (int i = 0; i<a.size(); ++i) {
if (a[i] != b[i]) {
temp--;
if (temp <= 0)return false;
}
}
return true;
}
};



127.上一题的简化版,求最短路径的长度

(换了个思路,BFS,因为单词过多的时候两两太慢了…所以干脆把所有的都罗列出来

用了unordered_set  可以很方便得erase....

class Solution {
public:
int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
if (beginWord.size() != endWord.size())return 0;
unordered_set<string>dist;
deque<string>path(1, beginWord);
for (int i = 0; i < wordList.size(); ++i)dist.insert(wordList[i]);
return ladderLength(endWord, dist, path);
}
int ladderLength(string endWord, unordered_set<string>& dist, deque<string>&path) {
//不计算两两的关系,而是把所有关系都罗列出来,总共就26个字母,所以会快很多
if (dist.find(endWord) == dist.end())return 0;//结束单词不在列表里

int result = 1;
int nums = 1;//该层有单词的个数

while (nums-- && !path.empty()) {

for (int i = 0; i < endWord.size(); ++i) {
string temp = path.front();
for (char a = 'a'; a <= 'z'; ++a) {
temp[i] = a;
if (temp == endWord)return result + 1;
if (dist.find(temp) != dist.end()) {
//找到了
dist.erase(temp);
path.push_back(temp);
}
}
}

path.pop_front();
if (nums == 0) { result++; nums = path.size(); }

}
return 0;

}
};


128.O(n)时间找出数组里最长连输数字的长度

利用了unordered_set里find函数的时间复杂度是O(1)!!!  参考

class Solution {
public:
int longestConsecutive(vector<int>& nums) {
unordered_set<int>temp (nums.begin(), nums.end());//赋值。。。
int result = 0;
for (auto a : nums) {
if (temp.find(a) == temp.end())continue;//没找到
temp.erase(a);
int left = a - 1, right = a + 1;
while (temp.find(left) != temp.end()) { temp.erase(left); left--; }
while (temp.find(right) != temp.end()) { temp.erase(right); right++; }
result = max(result, right - left - 1);
}
return result;
}
};


129.遍历二叉树,计算所有路径之和

Given a binary tree containing digits from 
0-9
 only, each root-to-leaf path could represent
a number.

An example is the root-to-leaf path 
1->2->3
 which represents the number 
123
.

Find the total sum of all root-to-leaf numbers.

For example,
1
/ \
2   3


The root-to-leaf path 
1->2
 represents the number 
12
.

The root-to-leaf path 
1->3
 represents the number 
13
.

Return the sum = 12 + 13 = 
25
.

class Solution {
public:
int sumNumbers(TreeNode* root) {
int result = 0;
sumNums(root, result, 0);
return result;
}

void sumNums(TreeNode *root, int &result, int a) {
if (root) {
if (!root->left && !root->right)result += (10 * a + root->val);
if (root->left)sumNums(root->left, result, (10 * a + root->val));
if (root->right)sumNums(root->right, result, (10 * a + root->val));
}
}
};



130.类似围棋,消除所有被包围的O

Given a 2D board containing 
'X'
 and 
'O'
,
capture all regions surrounded by 
'X'
.

A region is captured by flipping all 
'O'
s into 
'X'
s
in that surrounded region.

For example,

X X X X
X O O X
X X O X
X O X X


After running your function, the board should be:
X X X X
X X X X
X X X X
X O X X


思路很明确:由四周向中间“生长”    BFS?

注意的是限制条件设置为>1,否则有一两个特例长度非常长而且都为‘O'的会runtime error...

class Solution {
public:
void solve(vector<vector<char>>& board) {
//由四周向里,有效的0变成1,最后再遍历一遍

if (board.size() == 0)return;
//先把最外圈的遍历一下
int height = board.size(), width = board[0].size();

for (int i = 0; i <height; ++i) {
if (board[i][0] == 'O')grow(board, i, 0);
if (board[i][width - 1] == 'O')grow(board, i, width - 1);
}

for (int i = 0; i <width; ++i) {
if (board[0][i] == 'O')grow(board, 0, i);
if (board[height - 1][i] == 'O')grow(board, height - 1, i);
}

for (int i = 0; i < height; ++i) {
for (int j = 0; j < width; ++j) {
if (board[i][j] == 'B')board[i][j] = 'O';
else board[i][j] = 'X';
}
}

return;

}
void grow(vector<vector<char>>& board, int i, int j) {
board[i][j] = 'B';
if (i - 1 >0 && board[i - 1][j] == 'O') {
grow(board, i - 1, j);
}
if (i + 1<board.size()-1 && board[i + 1][j] == 'O') {
grow(board, i + 1, j);
}
if (j - 1 >0 && board[i][j - 1] == 'O') {
grow(board, i, j - 1);
}
if (j + 1<board[0].size()-1 && board[i][j + 1] == 'O') {
grow(board, i, j + 1);
}

}

};


这十条前后横跨了好几个月。。。尴尬…

然后重装系统后丢了好多图,所以就先不配图了…


_(:з」∠)______    (这样显得腿长

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  BFS wordladder leetcode