zoukankan      html  css  js  c++  java
  • 字符串问题简述与两个基本问题的Java实现——判断二叉树拓扑结构关系与变形词

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

    (解题金句:其他问题字符串化,然后调用String类封装方法解决问题; 字符串问题数组化,然后操作字符数组解决问题。)

    (从字符串中寻找某种性质的子串问题,与从二叉树中寻找某种性质的子树相类似,解题思路为从头到尾模拟拼写字符串的过程,对拼写过程中的每一个字符,对已拼写的子串的进行性质判断,更新相关信息。当拼写到结尾时,记录下的信息即为所求。)

    一:字符串问题简述

        字符串相关问题通常有以下特性:

        1:字符串数组化:对于一个字符串,通常看作一个字符数组来处理,常见的有数组排序、调整、查找等。

        2:其他问题字符串化:很多问题可以用字符串来模拟、处理

        关于字符串的一些常见概念:

        1:回文:一个字符串,从左到右读和从右到左读是完全一样的。

        2:子串:字符串中任意个连续的字符组成的子序列称为该串的子串。

        3:子序列:子序列就是在原来字符串中找出一部分字符(不强制连续)组成的序列。

        4:递增子序列: 首先它是子序列,其次它们的元素是递增的。

        5:最长子序列:子序列中元素的个数是最多的那一序列。

        6:公共子序列:子序列的元素必须在两个字符串中都要出现。

        7:前缀树:从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。

        8:后缀树:后缀树中存储的关键词为所有的后缀。

        9:字符串匹配:其输入是原字符串(String)和子串(又称模式,Pattern)组成,输出为子串在原字符串中的首次出现的位置。常见算法有暴力搜索(Brute force),KMP, BM(Boyer Moore)等等。【注:一般面试问匹配算法的实现思路,而做题则是使用匹配结果即可,Java中封装了String.contains()/String.indexOf()方法了】

        常见字符串操作:

        1:替换

        2:变形

        3:拼接

        常见字符串题型:

        1:规则判断:字符串是否符合某种规则、格式

        2:模拟数字运算

        3:字符串数组化处理:字符数组的调整、查找、排序等

        4:字符统计问题

        5:动态规划:最长公共子串、最长公共子序列、最长回文子串、最长回文子序列...

        6:搜索类型:用DFS/BFS模拟字符串变换的过程,从中获取解

        7:字符串匹配问题:从str1中查找str2

    二:两棵树拓扑结构比较问题

        给出两棵二叉树树,判断树2是否为树1的某棵子树。

        解法:按照同一种遍历规则,序列化两棵二叉树,把问题转化为字符串匹配问题——str1中是否包含str2子串。

    public static void preOrder(TreeNode root,ArrayList<String> pre){
            if(root==null){//1:遍历到叶子结点的左右儿子,用#表示空结点
                pre.add("#");
                return;
            }
            Integer value=root.val;
            pre.add(value.toString());
            preOrder(root.left,pre);
            preOrder(root.right,pre);
        }
        public static boolean chkIdentical(TreeNode A, TreeNode B) {
            ArrayList<String> listA=new ArrayList<String>();
            ArrayList<String> listB=new ArrayList<String>();
            
            //遍历两棵树
            preOrder(A,listA);
            preOrder(B,listB);
            
            //把树的遍历结果转为字符串
            StringBuilder builderA=new StringBuilder();
            for(String i:listA){
                builderA.append(i);
            }
            String strA=builderA.toString();
            StringBuilder builderB=new StringBuilder();
            for(String j:listB){
                builderB.append(j);
            }
            String strB=builderB.toString();
            
            //判断A树序列中是否有B树序列
            return strA.contains(strB);
        }

    三:变形词

        变形词定义:字符串str1中字符种类以及各字符出现次数,与字符串str2中种类及出现次数一致,则str1和str2互为变形词。

        思路:使用两个hashMap,分别统计str1和str2中各字符出现次数即可。注意特殊情况:两字符串长度不同,则绝对不互为变形词。

    public boolean chkTransform(String A, int lena, String B, int lenb) {
            if(lena!=lenb){
                return false;
            }
            char[] charsA=A.toCharArray();
            char[] charsB=B.toCharArray();
            HashMap<Character,Integer> mapA=new HashMap<Character,Integer>();
            HashMap<Character,Integer> mapB=new HashMap<Character,Integer>();
            for(Character ch:charsA){
                if(mapA.get(ch)==null){
                    mapA.put(ch,1);
                }else{
                     mapA.put(ch,mapA.get(ch)+1);
                }
            }
            for(Character ch:charsB){
                if(mapB.get(ch)==null){
                    mapB.put(ch,1);
                }else{
                     mapB.put(ch,mapB.get(ch)+1);
                }
            }
    //如果字符种类数不一样,则直接返回false
    if(mapA.size()!=mapB.size()){ return false; }
    //由于不知道具体哪些种类,那么直接取两字符串拼接,遍历拼接后字符串每个字符即可得到两字符串所有种类 String sum
    =A+B; char[] sumchars=sum.toCharArray(); for(Character ch:sumchars){ if(mapA.get(ch)!=mapB.get(ch)){//无论哪一个字符,只有A,B中数量不相等,则返回false return false; } } return true; }
  • 相关阅读:
    Reactive Extensions (Rx) 入门(5) —— Rx的事件编程
    Reactive Extensions (Rx) 入门(4) —— Rx的事件编程
    Reactive Extensions (Rx) 入门(3) —— Rx的事件编程
    Reactive Extensions (Rx) 入门(2) —— 安装 Reactive Extensions
    Reactive Extensions (Rx) 入门(1) —— Reactive Extensions 概要
    Xamarin NuGet 缓存包导致 already added : Landroid/support/annotation/AnimRes 问题解决方案
    Android 系统Action大全
    Xamarin Forms 实现发送通知点击跳转
    如何理解灰度发布
    推荐一款分布式微服务框架 Surging
  • 原文地址:https://www.cnblogs.com/ygj0930/p/6851631.html
Copyright © 2011-2022 走看看