Substring with Concatenation of All Words, 返回字符串中包含字符串数组所有字符串元素连接而成的字串的位置

问题描述:给定一个字符数组words,和字符串s,返回字符数组中所有字符元素组成的子串在字符串中的位置,要求所有的字符串数组里的元素只在字符串s中存在一次。

算法分析:这道题和strStr很类似。只不过strStr是子串,而这个题是字符串数组里的元素组成的子串,字符串数组里的元素是无序的,但是必须全部包含。所有考虑使用map集合。关键点在于几个临界值,字符串元素在s中重复了怎么做,找到一个符合的子串后怎么做,有字符串元素不匹配怎做。

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class SubstringwithConcatenationofAllWords {

    public List<Integer> findSubstring(String s, String[] words) {

        ArrayList<Integer> result = new ArrayList<Integer>();
        if(s==null||s.length()==0||words==null||words.length==0){
            return result;
        } 

        //frequency of words
        HashMap<String, Integer> map = new HashMap<String, Integer>();
        for(String w: words){
            if(map.containsKey(w)){
                map.put(w, map.get(w)+1);
            }else{
                map.put(w, 1);
            }
        }

        int len = words[0].length();

        for(int j=0; j<len; j++)
        {
            HashMap<String, Integer> currentMap = new HashMap<String, Integer>();
            int start = j;//起始下标,因为len为窗口大小,所以起始下标只需在0-len之间循环,就像取模一样,超过了,就重复了。
            int count = 0;//记录满足的字符串数量

            for(int i=j; i<=s.length()-len; i=i+len)
            {
                String sub = s.substring(i, i+len);
                if(map.containsKey(sub))
                {
                    if(currentMap.containsKey(sub))
                    {
                        currentMap.put(sub, currentMap.get(sub)+1);
                    }
                    else
                    {
                        currentMap.put(sub, 1);
                    }

                    count++;
                    //只要发现子字符串中有重复的字符数组中的元素,那么就从起始位置循环删除字符串.
                    //也就是说重复了,就逆向操作,直至只包含一个重复的那个字符串。
                    while(currentMap.get(sub)>map.get(sub))
                    {
                        //四个基本逆向操作。重复了或匹配成功了都要进行窗口滑动。
                        String left = s.substring(start, start+len);
                        currentMap.put(left, currentMap.get(left)-1);
                        count--;
                        start = start + len;
                    }

                    if(count==words.length)//字符串包含所有字符数组中的元素,
                    {
                        result.add(start); //将起始位置加入result
                        //四个基本逆向操作。窗口滑动。窗口值为len
                        String left = s.substring(start, start+len);
                        currentMap.put(left, currentMap.get(left)-1);
                        count--;
                        start = start + len;
                    }
                }
                else
                {
                    currentMap.clear();
                    start = i+len;
                    count = 0;
                }
            }
        }

        return result;
    }
}

StrStr算法如下:

public int strStr(String haystack, String needle) {

        if(haystack == null || needle == null)
        {
            return -1;
        }

        for (int i = 0; i <= (haystack.length()-needle.length()); i++)
        {
            int m = i;
            for (int j = 0; j < needle.length(); j++)
            {
                if (needle.charAt(j) == haystack.charAt(m))
                {
                    m++;
                    if((m-i) == needle.length())
                    {
                        return i;
                    }
                }
                else
                {
                    break;
                }
            }
        }
        return -1;
    }
时间: 2024-10-09 20:07:55

Substring with Concatenation of All Words, 返回字符串中包含字符串数组所有字符串元素连接而成的字串的位置的相关文章

找出n个字符串中出现次数最多的字符串。

1. 找出n个字符串中出现次数最多的字符串. C/C++: char* find(char **data,int n); Java: String find(String data[]); 说明: 1. data是字符串数组,n是数组中字符串的个数,返回值为出现次数最多的字符串. 2. 若结果有多个,返回任意一个即可 3. 不得使用任何库函数/API,如需使用类似功能, 请自行实现 4. 算法效率尽可能高,尽量少的使用内存空间 5. 必须要有代码注释和算法说明. 例如:data里面的数据是{“p

将字符串中的三个单词的首字母转化成大写

<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title> <script> //var a = 'welcome to china'; //将字符串中的三个单词的首字母转化成大写:返回Welcome To China; var a = 'welcome to china'; va

Oracle字符串中包含数字、特殊符号的排序

问题描述: 某小区,需要按照小区.楼栋.单元号.房间号进行排序,但是按照地址描述排序时,因为字符串中包含数字,所以造成了如下的结果, 1号楼之后应该是2号楼,但是查询结果却是10号楼 . 尝试解决 使用正则表达式替换 结果: 虽然楼栋号排序正常了,但是会发现房间号排序出现了混乱.  继续想办法 终极办法: 使用translate函数 可以发现,结果正常显示 . 以下附上translate使用方法 一.语法: TRANSLATE(string,from_str,to_str) 二.目的 返回将(所

C语言:从p所指字符串中找出ASCII码最大的字符,将其放在第一个位置上,并将该字符前的原字符向后顺序移动。

//fun函数:从p所指字符串中找出ASCII码最大的字符,将其放在第一个位置上,并将该字符前的原字符向后顺序移动. 1 #include <stdio.h> 2 void fun( char *p ) 3 { char max,*q; int i=0; 4 max=p[i]; 5 while( p[i]!=0 ) 6 { if( max<p[i] ) 7 { max=p[i]; 8 /**********found**********/ 9 q = p + i;//先找到最大值,记录最

用C#通过正则表达式截取字符串中符合条件的子字符串

仅仅作为简单的记录,不多说直接上代码(仅测试使用): private void Test() { Regex ConnoteA = new Regex("^[a-zA-Z]\\d{8}$"); Regex ConnoteAA = new Regex("^[a-zA-Z]{2}\\d{7,10}$"); Regex ConnoteAAA = new Regex("^[a-zA-Z]{3}\\d{5,9}$"); Regex ConnoteAAAA

关于“C语言中的字符数组和字符串”一些需要注意的基础点

在C语言中,没有类似Java的String类对字符串的处理,字符串的包装可以采用字符数组. 先看字符数组: #include<stdio.h> void main() { char array[] = {'a','b','c'}; int str = sizeof(array)/sizeof(char); printf("%d",str); } 此时的输出结果为:3,即字符数组的长度为3. 下面我们用字符串初始化字符数组,代码如下. #include<stdio.h&

C# String.Format格式化json字符串中包含"{" "}"报错问题

json.Append(String.Format("{\"total\":{0},\"row\":{1}}", lineCount, strJSON));直接会报错 字符串中包含{或者},则需要用{{ 来代替字符 {,用}} 代替 }如:json.Append(String.Format("{{\"total\":{0},\"row\":{1}}}", lineCount, strJS

判断字符串中包含3个连续(升、降)或相同的数字

有网友问及“asp.net怎么判断一个手机号字符串中包含3个连续的字符或3个相同的字符?”: Insus.NET做了一下练习,并把方法分享,希望网友们能从中获取一些启示.面向对象嘛,先写一个Number类,用来处理号码之用,很是一个很简单的类,一目了然. #38至#41的方法,IsUpNumber()判断是否为连续升序的数字.#43至#46的方法,IsDownNumber()判断是否为连续降序的数字.#48至#51的方法,IsSameNumber()判断是来为连续相同的数字.#53至#57的方法

请编写程序,统计键盘录入的字符串中出现了几次字符串”java”,并测试

import java.util.Scanner;public class StringBufferText {//main方法public static void main(String[] args) {br/>@SuppressWarnings("resource")//键盘录入Scanner sc=new Scanner(System.in);//字符串数据的导入System.out.println("请您输入一个字符串:");String str=s