算法题摘录六

转载请注明原文地址: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]!='\0')时,则匹配当前字符,开始匹配下一个字符;

直到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++移动窗口。

 

转载于:https://www.cnblogs.com/ygj0930/p/6442734.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值