1:山羊拉丁文
Java
分析:
首先,根据山羊拉丁文的规则,要输入一行英文字母的句子,所以用 **String**;
然后再用split函数将句子以空格分割开存成数组形式
然后再根据山羊拉丁文的相应规则进行相应的变换。使用 for 循环遍历每一个单词
的第一个字母,在进行相应的变换,再返回对应的单词。
遍历代码如下:
for(int i=0;i<str.length;i++){
if(str[i].startsWith("a")||str[i].startsWith("e")||str[i].startsWith("i")
||str[i].startsWith("o")||str[i].startsWith("u")||str[i].startsWith("A")
||str[i].startsWith("E")||str[i].startsWith("I")||str[i].startsWith("O")
||str[i].startsWith("U")) //判断他们的首字母是不是原因因素
{
str[i] += "ma";
}
else
{
str[i] = str[i].substring(1) + str[i].substring(0,1) + "ma";
}
for(int j=0;j<i+1;j++) //往单词后面添加相应个数的a
{
str[i] += "a";
}
res += str[i];
if(i != str.length-1){
res += " ";
}
}
这里用到了 String中的startWith和subString 方法。
startWith用于判断首字母是否为元音字母,
subString用于变换,它有两个参数,分别是变换的始末位置,其中第一个参数可以没有。
2:Bigram 分词
c++
分析:
Bigram 分词的规则,通俗一点讲,就可以这样理解。就是说:对于first的单词,就返回它后面的后面的单词。
要是没有那个单词就不返回,对于second的单词,就返回它后面的那个单词,同理,要是没有则不返回。
另外,每一个单词只能使用一次。
返回以后要将那个单词删除。鉴于此:应该使用vector动态数组存储单词。
用for循环将string类型的句子用vector数组存起来
text+=' ';
vector<string> stext,res; //定义String类的vector数组
for(int i=0;i<text.size();i++){
if(text[i]==' ') {
stext.push_back(s); // 在stext的末尾插入单词
s="";
}else {
s+=text[i];
}
}
储存完以后判断
//如果不够三个单词则直接返回 res
if(stext.size()<3) return res;
根据规则用 for循环 遍历vector数组中的内容(vector是动态数组,动态分配存储空间,这也是用vector数组的原因),然后将res返回
old1=stext[0],old2=stext[1];
for(int i=2;i<stext.size();i++){
if(old1==first&&old2==second) res.push_back(stext[i]);
old1=old2;
old2=stext[i];
}
return res;
3: 三角形最小路径和
C++
DP动态规划
参考了一个 da lao 的解题思路。思路如下:
在设置一个一维数组,将triangle数组中每一行的值都加上上一行中的最小值。
然后再将最后一行存在一位数组中,输出该数组中的最小值就是答案。
三角形用vector中包含vector的数组存储,首先用 size() 函数获取三角形的行数,若为非正数,则返回0;其余的进行动态dp。设初值为0;
int m = triangle.size();
if(m <= 0) return 0;
int dp[m] = {0};
dp[0] = triangle[0][0];
for(int i = 1; i < m;i++){
dp[i] = triangle[i][i]+dp[i-1];
for(int j = i-1 ; j > 0;j--){
dp[j] = triangle[i][j] + min(dp[j-1],dp[j]);
}
dp[0] += triangle[i][0];
}
然后再找出一位数组中最小的数即为答案
int res = dp[0];
for(int i=1; i<m;i++){
res = min(dp[i],res);
}
这是把平面的问题改成了一维的问题然后判断大小,然后解决问题!
4: 叶子相似的树
C++
这个题一点思路都没有,后来查看了题解和源代码才懵懵懂懂的看懂
这个题主要判断的是两颗二叉树的叶值序列,如果相同则为true,反之为false
大神的思路
首先,要找出二叉树的叶值序列。
然后在比较它们是否相等。
如何找出叶值序列呢?
大神给出了深度优先搜索的算法。
vector<int> r1,r2;
bool leafSimilar(TreeNode* root1, TreeNode* root2) {
//将两个二叉树的叶子节点分别放进两个vector数组中,然后判断两个vector数组中的内容是否相等即可
digui(root1,r1);
digui(root2,r2);
if(r1 == r2) return true; // 叶值序列相等
return false; //不相等
}
/// 递归算法
void digui(TreeNode* root,vector<int>& res){
if(!root) //如果TreeNode 为空 ,则返回
return;
digui(root->left,res); //分别递归
if(!root->left && !root->right)
res.push_back(root->val);
digui(root->right,res);
}
5:二叉树中所有距离为K的结点
这个题毫不夸张地说,我一点都不会做,两点也不会做,唉!
因为没有看懂大神的解题思路,所以也就不敢在这里大言不惭
附上大神代码,还请大家不吝赐教
class Solution {
public:
vector<int> distanceK(TreeNode* root, TreeNode* target, int K) {
vector<int> ans;
find(ans, root, target, K);
return ans;
}
int find(vector<int>& ans, TreeNode* root, TreeNode* target, int K){
if(!root)
return INT_MAX;
if(root==target){
depth(ans,target,0,K);
return 0;
}
int l = find(ans,root->left,target,K);
int r = find(ans,root->right,target,K);
if(l==INT_MAX&&r==INT_MAX)
return INT_MAX;
else if(l==INT_MAX){
if(r+1==K)
ans.push_back(root->val);
else if(r<K)
depth(ans,root->left,0,K-r-2);
return r+1;
}
else if(r==INT_MAX){
if(l+1==K)
ans.push_back(root->val);
else if(l<K)
depth(ans,root->right,0,K-l-2);
return l+1;
}
return INT_MAX;
}
void depth(vector<int>& ans, TreeNode* root, int d, int K){
if(!root)
return;
if(d==K){
ans.push_back(root->val);
return;
}
depth(ans,root->left,d+1,K);
depth(ans,root->right,d+1,K);
}
};
现在才发现,所谓上的思路很重要是没有任何问题的,但是coding能力同样重要,二者不分上下,至少在我这里,我是这样认为的。