zoukankan      html  css  js  c++  java
  • 算法题摘录六

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6442734.html

    1:正则表达式匹配

    如果pattern[curr+1]=='*'时,表示pattern[curr]可能出现0次,1次,或任意多次。那么下一次的匹配就有可能是:

    出现0次:pattern[curr+2]与str[curr]比较

    出现1次:pattern[curr+2]与str[curr+1]比较

    出现多次:pattern[curr]与str[curr+1]比较

    这三种情况都可能出现,递归这三种情况取或即可。

    而每一位pattern匹配str,当pattern[curr]==str[curr]||(pattern[curr]=='.'&&str[curr]!='')时,则匹配当前字符,开始匹配下一个字符;

    直到pattern和str都匹配到了末尾,说明字符串是这个正则表达式的句子,否则,只要其中一处不相等或者表达式到末尾而字符串还没匹配完,就不是它的句子。

    2:判断字符串是否表示一个数值

    形如 +100、5e2,-123之类的都是能表示数字的字符串。而12e、1ab2、+-3之类的则不是。

    此题其实就是判断输入的字符串是否匹配  数字  的正则表达式:[sign] digits [[.][digits]] [e|E [sign]digits]

    遍历输入的字符串,开头如果有+-号的一个,则匹配sign,匹配下一个;

    遍历数字,如果遇到  '.' ,转入匹配小数,小数部分只能是纯数字;如果遇到e|E,则转入匹配科学记数法,后面如果有符号则只能正负号中其中一个1个,符号之后只能是纯数字;

    3:字符中第一个不重复的字符

    首先遍历一次字符串,对每一个字符,map.get(ch),如果无对象返回的话说明ch第一次出现,则插入map,令值为1;如果有返回,则说明重复了,更新其值为-1;

    然后在第二次遍历字符串时,读到都一个value=-1的就是第一个不重复的字符了。

    4:找到链表中环的入口结点

    链表有环是指:尾结点的next指针指向了链表中的某一个结点形成了环。比如:1-2-3-4-5->3(5是尾结点,指向了3)

    我们假设两个指针p1,p2遍历这个链表,p2比p1多遍历了一圈环后到达尾结点。则p2的遍历路程为:1-2-3-4-5-3-4-5  而p1遍历到尾结点:1-2-3-4-5,可以发现p2比p1多走了环的结点数步才到达尾结点。那么p2与p1的步数差刚好为环结点数,那么如果我们令p2先走环结点数步,然后p1在开始移动,之后p1、p2同时移动,当p1指向环的入口时,p2比p1多环结点数步,所以p2刚好走完了一次环,回到环入口,所以此时p1==p2。那么我们就找到了环的入口。

    5:删除有序链表中重复的结点:1-2-2-3变成1-3

    我们用pre记录当前结点,然后遍历一个结点pnext与pnext->next,如果相同,则令pnext=pnext->next跳过重复结点,循环此步,直到pnext!=pnext->next;那么期间的就是重复的结点,我们令pre->next=pnext->next即可把重复结点从链表中剔除;注意:头结点就开始重复的,找到第一个跟头结点不等的并且不重复的结点设为head即可删除开始就重复的结点。

    6:给出一个二叉树和一个结点,找出中序遍历中这个结点的下一个结点。每个结点除了有左右子结点指针外还有一个指向父节点的指针。

    解法1:我们可以用一个数组保存中序遍历的结果,然后遍历这个数组找到所给结点,它的下一个元素就是所求;

    解法2:按照中序遍历规律来找:

    如果所给结点有右子树,说明它是根结点,那么根据中序遍历“左根右”的顺序,它的右子树的最左子节点就是下一个结点,我们只需从右子结点一路左子节点直到找到最左子节点即可;

    如果所给结点没有右子树,并且它是父节点的左儿子,那么下一个遍历的就是它的父节点;

    如果所给结点既没有右子树,又不是父节点的左儿子,那么它的下一个遍历结点就是  第一个作为左儿子的祖先结点的父节点:我们从当前结点回溯父节点,并判断当前父节点是不是一个左儿子,不是的话继续上溯;直到当前祖先结点是其父的一个左儿子,那么该祖先结点的父节点就是下一个要遍历的结点;如果祖先结点到达树的根了,则说明所给结点是树的最右子节点,是中序遍历的最后遍历的那个结点。

    7:判断一颗二叉树是否对称

    解法一:对称的二叉树,其左右子树都是一样的。既然左右子树一样,那么我们根据 根左右 顺序遍历与  根右左  顺序遍历得到的序列应该是一样的。那么我们就可以定义一个 根左右 的遍历函数,一个 根右左 的遍历函数,得出两个序列一一进行比较即可。注意:这里有个特殊情况,各个结点的值一样,但是左右子树不对称,所以我们需要把子结点为null也作为一个值进行输出,作为遍历的序列的一个元素。

    解法二:递归法,只要找到有一层地方不对称即可:

    boolean isSame(MyTreeNode left,MyTreeNode right){
            //左右子树都是空,则说明树是对称的
            if(left==null && right==null){
                return true;
            }
            //当前层判断出不相等的就说明树是不对称的
            if((left==null&&right!=null)||(left!=null&&right==null)){
                return false;
            }
            if(left.val!=right.val){
                return false;
            }
            //否则,需要从下一层去判断
            return isSame(left.leftNode, right.rightNode)&&isSame(left.rightNode, right.leftNode);
            
        }

    8:之 字形打印二叉树

    即:按层打印,相邻层打印方向不同:一层从左往右,下一层就从右往左打印,再下层左往右......

    这种倒转顺序的情况,我们第一时间就想到——栈。因此打印每一层时,我们把位于下一层的子节点入栈;

    由打印规律我们可以推出:当前打印层是奇数层时,则先保存左子结点再保存右子节点到另一个栈;如果是偶数层则先右后左保存子节点到另一个栈;每一个栈为空时“攻防互换”开始打印下一层;

    9:序列化二叉树和反序列化二叉树

    序列化二叉树是指:按前/中/后顺序遍历二叉树时,遇到null就用一个符号表示,比如 $ 符号。

    void Serialize(MyTreeNode root){
            if(root==null){
                System.out.println("$,");
                return;
            }
            System.out.println(root.val+',');
            Serialize(root.leftNode);
            Serialize(root.rightNode);
        }

    反序列化二叉树是指:给定一个二叉树的序列化表示以及遍历规则,重构出一棵二叉树。

    10:BST中第K大的结点

    BST的中序遍历是一个增序的数组,该数组第K个元素就是BST中第K大结点。

    11:求滑动窗内的最大值

    给定一个数组,以k大小的滑动窗来遍历元素,求每个窗的最大值。

    第一个窗包含了0~k-1下标的元素,之后窗口逐渐移动,可知总共移动了length-k步。

    那么我们就可以这样做了:用一个数组存放元素,用两个间隔为k-1的下标维持一个一个大小为k的窗口:index1~index2刚好包含了k个元素。每次遍历index1~index2找到当前窗口最大值,然后index1++,index2++移动窗口。

  • 相关阅读:
    Android 按键消息处理Android 按键消息处理
    objcopy
    SQLite多线程读写实践及常见问题总结
    android动画坐标定义
    Android动画效果translate、scale、alpha、rotate
    Android公共库(缓存 下拉ListView 下载管理Pro 静默安装 root运行 Java公共类)
    Flatten Binary Tree to Linked List
    Distinct Subsequences
    Populating Next Right Pointers in Each Node II
    Populating Next Right Pointers in Each Node
  • 原文地址:https://www.cnblogs.com/ygj0930/p/6442734.html
Copyright © 2011-2022 走看看