今日份:
1.已知一棵二叉树,求它每层结点的平均值。
感觉也也是一道基础高危题,在层次遍历上稍微做了一下调整,在正常层次遍历的基础上多加入一个队列,用于记录每层结点的个数,和计算每层各结点的数值和。
List<double> AverageTree(Tree root)
{
if(root == null)
{
return null;
}
List<double> result = new List<double>();
Queue q = new Queue();
q.Enqueue(root);
while(q.Any())
{
Queue tmp = new Queue();
int sum = 0;
int count = 0;
while(q.Any())
{
Tree t = (Tree)q.Dequeue();
sum += t.val;
count++;
if(t.left != null)
{
tmp.Enqueue(t.left);
}
if(t.right != null)
{
tmp.Enqueue(t.right);
}
}
result.Add(sum * 1.0 / count);
q = tmp;
}
return result;
}
2.
这道题我用了2个函数辅助求左右子树的和以及差,也是写了好多行(lll¬ω¬),而且还是看了提示才明白题的意思,所以为了加深印象,把自己写的难看的但便于自己理解的代码和别人写的好看的代码都记下
自己麻烦的做法:
int FindTilt(Tree root)
{
//主函数
if(root == null)
{
return 0;
}
return Minus(root.left) + Minus(root.right) + Math.Abs(Plus(left) - Plus(right));
}
int Plus(Tree root)
{
//求树的各结点和
if(root == null)
{
return 0;
}
return root.val + Plus(root.left) + Plus(root.right);
}
int Minus(Tree root)
{
//求树的每层结点的差的和
if(root = null)
{
return 0;
}
int minusSum = 0;
Queue q = new Queue();
q.Enqueue(root);
while(q.Any())
{
int lv = 0;
int rv = 0;
Tree tmp = (Tree)q.Dequeue();
if(tmp.left != null)
{
q.Enqueue(tmp.left);
lv = Plus(tmp.left);
}
if(tmp.right != null)
{
q.Enqueue(tmp.right);
rv = Plus(tmp.right);
}
minusSum += Math.Abs(lv - rv);
}
return minusSum;
}
别人的:
int sum = 0;
int FindTilt(Tree root)
{
//主函数
if(root == null)
{
return 0;
}
Calculate(root);
return sum;
}
int Calculate(Tree item)
{
if(item == null)
{
return 0;
}
int lv = Calculate(item.left);
int rv = Calculate(item.right);
sum += Math.Abs(lv - rv);
return lv + rv + item.val;
}
进而我发现我自己写的Minus版本完全就可以用主函数的递归替代了,因为Minus里进行的操作和主函数最后返回的都是“左减右的绝对值”,所以把Minus删掉,保留Plus函数,主函数可以直接写成:
int FindTilt(Tree root)
{
if(root == null)
{
return 0;
}
return FindTilt(root.left)+FindTilt(root.right)+Math.Abs(Plus(root.left)-Plus(root.right));
}
这样看起来更舒服一些。
3.
“易位构词游戏,判断t是不是s的易位词”,这道题我做的时候用了Dictionary,很浪费空间的把两个字符串倒到了两个dictionary里,然后再比较两个dictionary。而看了别人的代码发现用两个大数组就够了(lll¬ω¬)。。。
自己的:
bool IsAnagram(string s, string t)
{
if(s == null || t == null)
{
return false;
}
if(s.Length != t.Length)
{
return false;
}
Dictionary<char, int> dicS = new Dictionary<char, int>();
Dictionary<char, int> dicT = new Dictionary<char, int>();
//返回true的条件为两字符串长度相等,其中各字母相同且数量相等,所以建立了字符对应个数的字典。
for(int i = 0; i < s.Length; i++)
{
if(dicS.ContainsKey(s[i]))
{
dicS[s[i]]++;
}
else
{
dicS.Add(s[i], 1);
}
}
for(int i = 0; i < t.Length; i++)
{
if(dicT.ContainsKey(t[i]))
{
dicT[t[i]]++;
}
else
{
dicT.Add(t[i], 1);
}
}
foreach(KeyValuePair<char, int> kvpS in dicS)
{
//如果t中没有s中的某个字母返回false
if(!dicT.ContainsKey(kvpS.Key))
{
return false;
}
//如果t中某个字母的个数和s中的不相等返回false
if(dicT[kvpS.Key] != kvp.Value)
{
return false;
}
}
return true;
}
别人的:
bool Anagram(string s, string t)
{
if(s == null || t == null)
{
return false;
}
if(s.Length != t.Length)
{
return false;
}
char[] arr1 = new char[256];
char[] arr2 = new char[256];
for(int i = 0; i < s.Length; i++)
{
arr1[s[i]]++;
arr2[t[i]]++;
}
return new string(arr1).Equals(new string(arr2));
}
然后发现,如果用排序的话写起来更简单( ╯□╰ ) (怎么能把排序忘了呢。。。):
bool Anagram(string s, string t)
{
char[] sc = s.ToCharArry();
char[] tc = t.ToCharArry();
Array.Sort(sc);
Array.Sort(tc);
return Array.Equals(sc, tc);
}
4.找出字符串s中第一个没有重复字符的字符序号,没有则返回-1(假设字符串只包含小写字母)
又是一道让我写复杂的题,也是用了dictionary和List,其实只要一个数组就好了
int FindUniqueCharacter(string s)
{
if(s == null)
{
return -1;
}
int[] freq = new int[26];
for(int i = 0; i < s.Length; i++)
{
++freq[s[i] - 97];
}
for(int i = 0; i < s.Length; i++)
{
if(freq[s[i] - 97] == 1)
{
return i;
}
}
return -1;
}