学习数据结构的第四天



class Solution {
    private class BST<E extends Comparable<E>> 
    { //这里也是暗含乾坤,必须extends呀
        private Node root;
        private int size;
        private class Node
        {
            E value;
            Node left;
            Node right;
            public Node(E e)
            {
                value=e;
                left=null;
                right=null;
            }
        }
        public boolean contains(E e)
        {
            return contains(this.root,e);
        }
        private boolean contains(Node node,E e)
        {
            if(node==null)
                return false;
            if(node.value.equals(e))    //如果是引用类型的话,那么就是.equals
                return true;
            if(node.value.compareTo(e)>0)
                return contains(node.left,e);
            if(node.value.compareTo(e)<0)
                return contains(node.right,e);
            return false;
        }
        public void add(E e)
        {
            this.size++;
            root=add(this.root,e);
        }
        public int getSize()
        {
            return this.size;
        }
        private Node add(Node node,E e)  //add函数我写得实在是不行。
        {
            if(node==null)
            {
                 node=new Node(e);
                 return node;
            }
            if(node.value.compareTo(e)>0)
                node.left=add(node.left,e);
            if(node.value.compareTo(e)<0)
                node.right=add(node.right,e);
            return node;    
        }
    }

    public int uniqueMorseRepresentations(String[] words) 
    {
        // List<String> mosCode=new ArrayList<>();
         //之后再想,如果换成是其他的类似数组类型的存储咋整
        String []mosCode={".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.."};
        BST<String> bst=new BST<>();
        for(String word:words)
        {
            StringBuilder s=new StringBuilder();
            for(int i=0;i<word.length();i++) //数组是属性,然后字符串是函数。
            {
                int index=word.charAt(i)-'a';
                s.append(mosCode[index]);//这个stringbuilder应该用append
            }
            if(bst.contains(s.toString())!=true)
            {
                bst.add(s.toString());
            }
        }
        return bst.getSize();
    }
}
 
里面的小知识点:
1.    private class BST<E extends Comparable<E>>   对于bst而言,必须要这句话,因为没有这句话的话,那么E类型的数据未必带有比较的功能,所以bst建立的时候必须写这句
也就是说:如果你的数据必须带有比较功能,那么泛型那里必须写:e extends Comparable<E>
2.if(node.value.compareTo(e)==0  对于每个值,都必须用compareTo函数最好,因为的话你不知道这个值 是不是可以用==号来做,所以,比较大小,泛型最好用compareTo方法。
3.对于add函数的部分,必须要记住。add函数必须返回新添加的空间的地址,这是很重要的一点!不然的话这片空间的开拓是白开拓了。详见下面的代码

public void add(E e)
{
this.size++;
root=add(this.root,e);
}
public int getSize()
{
return this.size;
}
private Node add(Node node,E e) //add函数我写得实在是不行。
{
if(node==null)
{
node=new Node(e);
return node;
}
if(node.value.compareTo(e)>0)
node.left=add(node.left,e);
if(node.value.compareTo(e)<0)
node.right=add(node.right,e);
return node;
}
}

4.上面说的这件事情,就是说add函数,无论是什么东西的add函数,树结构的add函数,都应该这么写。返回新开拓的空间,并且新开拓的空间需要有人来接手。
5.数组类型的话,那么用大括号来做{}
6.什么时候用stringbuilder这种东西呢?

StringBuilder是可变对象,用来高效拼接字符串;

StringBuilder可以支持链式操作,实现链式操作的关键是返回实例本身;

StringBufferStringBuilder的线程安全版本,现在很少使用。

stringbuilder是可变对象,用来拼接字符串,也就是说:拼接频繁的话,那么用stringbuilder更划算。

7.然后的话对stringbuilder的对象进行拼接,用的是append函数。

对于String类型来说,虽然可以直接拼接字符串,但是,在循环中,每次循环都会创建新的字符串对象,然后扔掉旧的字符串。这样,绝大部分字符串都是临时对象,不但浪费内存,还会影响GC效率。

为了能高效拼接字符串,Java标准库提供了StringBuilder,它是一个可变对象,可以预分配缓冲区,这样,往StringBuilder中新增字符时,不会创建新的临时对象:

StringBuilder sb = new StringBuilder(1024);
for (int i = 0; i < 1000; i++) {
    sb.append(',');
    sb.append(i); } String s = sb.toString();
所以说,自己知道了什么时候应该用stringbuilder:多次拼接数据的时候。
自己知道了如何拼接,用append函数。
8.对于length来说,数组是一个属性length,字符串是一个函数length()。最后,从stringbuilder变为string,用tostring函数即可


对这道题目的思考:
1.BST到底是什么时候应该去用呢?BST的好处:中序遍历的话,那么值是从小到大排布的了。对于数据的存储,它提供了结构。可以让你知道这个东西是否在其中,以及数据是怎么排布的。
2.但是其实,bst到底是不是能用于实战呢?目前我觉得,如果说是从小到大排序的话,那么为什么不用排序算法,拍好了之后插入数组里面呢?存疑,因为这个可能比较麻烦一点,排序完之后还插入 消耗的时间多? 那么从小到大排布的话,那么确实是用bst比较方便
那么作为搜索的结构,set、list都可以实现contains的功能,用这两个岂不是更好?那么set的话可以防止重复,在这里面挺像需要的。
3.这里其实用set更好,用set重新实现一下试试。

用set成功实现了:

      Set<String> set=new HashSet<>();
       return set.size();

size是set里面的一个函数,其实的话不知道某个集合里面有什么函数,用.size()函数是可以猜猜的
set的话,确实更方便了。

 这里是说有排序的这个集合,也可以用TreeSet来实现。

TreeSet是有排序的集合实现。

所以说集合的话,防止了数据的重复,然后的话Treeset还保证了数据的顺序性。

那么这个BST按小到大排序的优点更加没有了,然后contains也能实现

所以说BST是树形结构来的,从左到右,从小到大的树形结构。

那么自己写BST的这个好处,确实好像没什么好处了。那么自己学会了怎么写BST,具体应用的话,好像确实是set之类的比较好。

T102 二叉树的层次遍历:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        // 层次序遍历,那么是栈或者queue,栈 先进后出
        //那么是把相应的右孩子先推进栈里面去。
        //层次序遍历的问题:每层的数量是不一定的。那么pop出来之后,直到空之后,再进行输入的操作。
        Deque<TreeNode> dq=new LinkedList<>();
        TreeNode node=root;  //这里不仅要输出,而且要告诉它,你的输出是第几层输出的。
        dq.push(node);//那么我认为在访问左、访问右孩子的时候做这件事吧
        //那么层次序遍历其实没必要啊,没必要用stack啊,我每次都输出四个不就好了
        //每一次需要输出几个是说不定的。
        //其实突然想到了,如果用栈的话,那么在脑海里面模拟一下栈的过程,其实很有利于自己思考得到结果的。
        List<List<Integer>> listResult=new ArrayList<List<Integer>>();//先pop出来,pop直到这个栈是空的,再能够去处理
        //pop出来,打印,并且放到数组里面。出口是什么?如果说pop出来的数组是空的话,那么说明添加进去的已经是空的了
        List<TreeNode> thisRoundNode=new ArrayList<TreeNode>();
        // thisRoundNode.add(root);
        boolean first=true;
        while(first || !thisRoundNode.isEmpty())
        {
            first=false;
            List<Integer> thisRound=new ArrayList<Integer>();
        while(!dq.isEmpty())
        {
            node=dq.pop();  //每次只pop一个,pop完了都不知道是哪里的人了。
            thisRound.add(node.val);//只要不是空的,那么就一直pop,pop完了之后添加到
            thisRoundNode.add(node);
        }
        listResult.add(thisRound);
        for(TreeNode n:thisRoundNode)
        {
            if(n.right!=null)
                dq.push(n.right);
            if(n.left!=null)
                dq.push(n.left);
        }                           
        }
        return listResult;
        }
}
 
上面是自己写的,自己总结一下:
1.栈这个东西,先进后出,因为每个层级都需要分别开来,那么我引入了list的数组
2.栈这个东西,我认为需要在脑海里面去理顺这个过程到底是怎么样,理顺了之后才能知道到底怎么去写代码。
错在哪里,不知道。
 

猜你喜欢

转载自www.cnblogs.com/startFrom0/p/12597487.html