Day25

9 篇文章 0 订阅
8 篇文章 0 订阅

自己什么时候才能摆脱这种:看见一道题,想半天没思路,需要看了答案才知道怎么做的弱鸡状态呢?郁闷( ̄﹏ ̄;)

今天份的题:

  1. 已知一个字符串s,它是由若干连续的0和若干连续的1组成的,求它包含多少个有相同数量的连续的0和1的子串(不包括空串和s本身)(子串内容可重复)
/**刚开始看了半天题也没明白是什么意思,后来看了答案才理解(lll¬ω¬),
它要求的子串是指,有相同个数的0和1,并且0是连续的,1也是连续的,
比如111000,000111,1100,0011,10,01这种的。
所以答案的解法是将s串中相同连续串的个数记录到一个数组中,
比如{3,3,3,2,2}这种可能表示s中从前到后有3个1,3个0,3个1,2个0,2个1。
这样遍历这个整数组的时候每次取相邻的两个元素中的最小值,记和的结果就是总数。**/

int CountBinarySubstrings(string s)
{
    if(s.Length <= 1)                          //s为空或只有一个0或1的情况
    {
        return 0;
    }
    List<int> countList = new List<int>();
    int count = 1;
    int result = 0;
    for(int i = 0; i < s.Length - 1; i++)
    {
        if(s[i] == s[i+1])
        {
            count++;
        }
        else
        {
            countList.Add(count);
            count = 1;
        }
        if(i == s.Length - 2)               //将s中最后一个字符记录下来
        {
            countList.Add(count);
        }
    }
    if(countList.Count < 2)                 //s中全为0或1的情况
    {
        return 0;
    }
    for(int i = 0; i < countList.Count - 1; i++)
    {
        result = result + Math.Min(countList[i], countList[i+1]);
    }
    return result;
}

2.已知一个正整数的搜索二叉树和一个正整数,求证该搜索二叉树中是否存在二个数,且满足这两个数的和等于已知的那个正整数

//因为已知是搜索二叉树,所以中序遍历该二叉树之后会得到一个从小到大排序好的数组,然后只要在数组中按“头+尾”的方式搜索符合条件的数即可。
bool FindTarget(Tree root, int t)
{
    if(root == null)
    {
        return false;
    }
    List<int> numList = new List<int>();
    Stack<Tree> stk = new Stack<Tree>();
    Tree nt = root;
    while(nt != null || stk.Any())
    {
        if(nt != null)
        {
            stk.Push(nt);
            nt = nt.left;
        }
        else
        {
            Tree tmp = stk.Pop();
            numList.Add(tmp.value);
            nt = tmp.right;
        }
    }
    int low = 0;
    int high = numList.Count - 1;
    while(low != high && low <= numList.Count - 1 && high >= 0)
    {
        if(numList[low] + numList[high] == t)
        {
            return true;
        }
        else if(numList[low] + numList[high] > t)
        {
            low++;
        }
        else
        {
            high--;
        }
    }
    return false;
}

这么做感觉代码不够简洁美观,又又又去看了答案,发现有一种利用Hash表的思路写出来看起来很简洁很美好,所以再次把别人的成果偷偷记下来

/**这个的思路是在遍历树的时候将每一个值记录到HashSet中,一旦在遍历的过程中发现目标值与当前值的差存在于HashSet中,就证明找到了**/
bool FindTarget(Tree root, int t)
{
    HashSet<int> htable = new HashSet<int>();
    return FindT(root, t, htable);
}
bool FindT(Tree root, int t, HashSet<int> hTable);
{
    if(root == null)
    {
        return false;
    }
    if(hTable.Contains(t - root.value))
    {
        return true;
    }
    hTable.Add(root.value);
    return FindT(root.left, t, hTable) || FindT(root.right, t, hTable);
}

3.问题3

//这道题读完题想到的是先序遍历非递归方式用Stack记录数字+设置一个记录访问过右结点的HashSet,所以按照先序遍历的非递归方式写,然后加入了各种临界判断,但是判断条件没有找准,结果越改越复杂还得不到正确结果(′д` )…彡…彡最终还是去腆着大脸看了答案/(ㄒoㄒ)/~~。。。

string Tree2str(Tree t)
{
    if(t == null)
    {
        return "";
    }
    if(t.left == null && t.right == null)
    {
        reutrn t.val;
    }
    if(t.right == null)
    {
        return t.val + "(" + Tree2str(t.left) + ")";
    }
    return t.val + "(" + Tree2str(t.left) + ")(" + Tree2str(t.right) + ")";
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值