面试经典

题目:最长子串

Minimum Window Substring

Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n).

For example, S = "ADOBECODEBANC" T = "ABC" Minimum window is "BANC".

Note: If there is no such window in S that covers all characters in T, return the emtpy string "".

If there are multiple such windows, you are guaranteed that there will always be only one unique minimum window in S.

双指针法

复杂度

时间 O(N) 空间 O(1)

思路

用一个哈希表记录目标字符串每个字母的个数,一个哈希表记录窗口中每个字母的个数。先找到第一个有效的窗口,用两个指针标出它的上界和下界。然后每次窗口右界向右移时,将左边尽可能的右缩,右缩的条件是窗口中字母的个数不小于目标字符串中字母的个数。

注意

  • 用一个数组来保存每个字符出现的次数,比哈希表容易
  • 保存结果子串的起始点初值为-1,方便最后判断是否有正确结果

代码

public class Solution {
    public String minWindow(String S, String T) {
        int[] srcHash = new int[255];
        // 记录目标字符串每个字母出现次数
        for(int i = 0; i < T.length(); i++){
            srcHash[T.charAt(i)]++;
        }
        int start = 0,i= 0;
        // 用于记录窗口内每个字母出现次数
        int[] destHash = new int[255];
        int found = 0;
        int begin = -1, end = S.length(), minLength = S.length();
        for(start = i = 0; i < S.length(); i++){
            // 每来一个字符给它的出现次数加1
            destHash[S.charAt(i)]++;
            // 如果加1后这个字符的数量不超过目标串中该字符的数量,则找到了一个匹配字符
            if(destHash[S.charAt(i)] <= srcHash[S.charAt(i)]) found++;
            // 如果找到的匹配字符数等于目标串长度,说明找到了一个符合要求的子串
            if(found == T.length()){
                // 将开头没用的都跳过,没用是指该字符出现次数超过了目标串中出现的次数,并把它们出现次数都减1
                while(start < i && destHash[S.charAt(start)] > srcHash[S.charAt(start)]){
                    destHash[S.charAt(start)]--;
                    start++;
                }
                // 这时候start指向该子串开头的字母,判断该子串长度
                if(i - start < minLength){
                    minLength = i - start;
                    begin = start;
                    end = i;
                }
                // 把开头的这个匹配字符跳过,并将匹配字符数减1
                destHash[S.charAt(start)]--;
                found--;
                // 子串起始位置加1,我们开始看下一个子串了
                start++;
            }
        }
        // 如果begin没有修改过,返回空
        return begin == -1 ? "" : S.substring(begin,end + 1);
    }
}

最长回文子串

回文字符串,指的是形式如同"abcba"或是"abccba“形式的字符串。

那么如何在一串给定的字符串中寻找其中最长的回文子串呢?

①动态规划

package uestc;

public class Main {

            public static void main(String[] args) {
                String s = "xccxbdc";
                String solu = longestPalindrome1(s);
                System.out.println(solu);

            }
            public static String longestPalindrome(String s) {
                int len = s.length();
                int maxLen = 0;
                String res = null;
                boolean[][] dp = new boolean[len][len];
                for(int i = len - 1;i >= 0;i--){
                    for(int j = i;j < len;j++){
                        dp[i][j] = s.charAt(i) == s.charAt(j) && (j - i < 3 || dp[i+1][j-1] == true);
                        //(1)当前遍历到的子串i~j是否是回文子串取决于i+1~j-1,也就是i~j中间的子串是否是回文并且s[i]是否等于s[j];
                        //(2)dp[i][j]是为true则意味着i~j是回文子串,则在下面判断后对res进行更新;如果为false,则该子串不是回文子串,开始遍历下一个子串。
                        if(dp[i][j] == true && (res == null || j - i + 1 > maxLen)){
                            //如果该子串长度更长,则更新res
                            res = s.substring(i, j+1);
                            maxLen = res.length();
                        }
                    }
                }

                return res;
            }
       }

②可以用延伸的思想来寻找,即先找最短的字符串如"a"、"bb"等,在这些字符串基础上进行延伸扩展,若是找到的符合要求的子串长度大于已找到的回文子串的最大长度,则取而代之,同时记录该子串的第一个字符的下标。

通过这种思想将字符串遍历执行即可找到最大回文子串。

public class PalindromicSubstring {
            private static int start;
            private static int maxLength;
            public static String longestPalindrome1(String s)
            {
                if(s.length()<2)
                      return s;
                for(int i=0;i<s.length()-1;i++)
                { //遍历整个数组,寻找回文子串最中间的字符,如果回文子串是奇数长度,那么最中间有一个字符;否则有两个字符
                         extendPali(s,i,i);
                         extendPali(s,i,i+1);    

                }
                return s.substring(start,start+maxLength);    

            }
            public static void extendPali(String s,int i,int j)
            {
                while(i>=0&&j<s.length()&&s.charAt(i)==s.charAt(j))
                {
                              i--;  //如果满足括号里的条件,则继续向两边扩展
                              j++;
                }
                if(maxLength<j-i-1){ //更新最大长度的值
                    start=i+1;
                    maxLength=j-i-1;
                }
            }

           }
            

原文地址:https://www.cnblogs.com/jinxingerhuo/p/9746939.html

时间: 2024-08-09 12:24:02

面试经典的相关文章

大公司面试经典数据结构与算法题C#解答

几个大公司(IBM.MicroSoft and so on)面试经典数据结构与算法题C#解答 1.链表反转 我想到了两种比较简单的方法 第一种是需要开一个新的链表,将原链表的元素从后到前的插入到新链表中(也就是原链表第一个元素被插入成新链表的最后一个元素). 第二种是不需要开新的链表,而是逐步反转原链表中元素的指向,例如: 原链表是 1->2->3->4->null  被  逐步修改为 ①2->1->null.3->4->null ②3->2->

0- 26个面试经典问题回答

面试技巧:26个面试经典问题回答 1.请你自我介绍一下自己好吗? ? 回答提示:一般人回答这个问题过于平常,只说姓名.年龄.爱好.工作经验,这些在简历上都有.其实,企业最希望知道的是求职者能否胜任工作,包括:最强的技能.最深入研究的知识领域.个性中最积极的部分.做过的最成功的事,主要的成就等,这些都可以和学习无关,也可以和学习有关,但要突出积极的个性和做事的能力,说得合情合理企业才会相信.企业很重视一个人的礼貌,求职者要尊重考官,在回答每个问题之后都说一句"谢谢",企业喜欢有礼貌的求职

JS面试经典题目

JavaScript开发人员在IT界的需求量一直很大.如果你非常精通神这门语言,你会有很多机会换工作,涨薪水.但是在一家公司录用你之前,你必须顺利通过面试,证明你的技能.在本文中,我将向您展示5个关于前端相关的问题,以测试侯选者的JavaScript技能和他们解决问题的能力.有将会非常有趣! 问题1:Scope作用范围 考虑下面的代码: 1 2 3 4 5 (function() {    var a = b = 5; })(); console.log(b); 什么会被打印在控制台上? 回答

面试经典数据库查询题目(学生、课程、选课)

这是前几天一刚毕业的朋友的面试题,算是面试常遇到的sql经典题目,记录一下(如图) 在此我在电脑数据库上建立了对应的表结构,以供检验sql语句正误. 建表语句: 学生表(student_info) CREATE TABLE `student_info` (    `no` varchar(255) NOT NULL,    `name` varchar(255) DEFAULT NULL,    `sex` varchar(255) DEFAULT NULL,    `age` int(10)

Java面试经典合集1:如何安全地删除List中的元素

package com.chendan.mianshi; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.stream.Collectors; public class MianShiTest1 { private static List<String> list = new ArrayList<String>(); public stati

《面试经典系列》- 从底层理解==和equals的区别

前言 在我们Java面试中,基础知识基本上比定会考核的点,而“==和equals的区别”则是面试官最喜欢.最经常问的问题. 但我们看了不少的文章.解释,总是一头雾水.一知半解的,往往很容忘记.今天,我带大家从底层去深入理解这两个玩意的区别,相信下次面试官再问的时候,肯定能镇住面试官. 一.初始“==”的含义 在Java中,“==”的作用主要有两个: 1.基础数据类型:比较的是两者的值是否相等,比如两个 int 类型的变量,比较的是变量的值是否相等. 2.引用数据类型:比较的是引用地址是否相同,比

oracle面试经典题

1.sql面试题(学生表_课程表_成绩表_教师表) 2. 问题描述: 本题用到下面三个关系表: CARD 借书卡. CNO 卡号,NAME 姓名,CLASS 班级 BOOKS 图书. BNO 书号,BNAME 书名,AUTHOR 作者,PRICE 单价,QUANTITY 库存册数 BORROW 借书记录. CNO 借书卡号,BNO 书号,RDATE 还书日期 备注:限定每人每种书只能借一本:库存册数随借书.还书而改变. 3. 问题描述: 为管理岗位业务培训信息,建立3个表: S (S#,SN,S

java面试 - 经典算法题

题目一: public class testClockwiseOutput { //顺时针打印一个矩阵 @Test public void test(){ int[][] num = new int[100][100]; int n = 4; int count =1; for(int i=0;i<n;i++){ for(int j =0;j<n;j++){ num[i][j]=count++; } } output(num,0,n-1); } public void output(int[]

.NET面试经典问答

用.net做B/S结构的系统,您是用几层结构来开发,每一层之间的关系以及为什么要这样分层? 答:从下至上分别为:数据访问层.业务逻辑层(又或成为领域层).表示层 数据访问层:有时候也称为是持久层,其功能主要是负责数据库的访问 业务逻辑层:是整个系统的核心,它与这个系统的业务(领域)有关 表示层:是系统的UI部分,负责使用者与整个系统的交互.  优点:  分工明确,条理清晰,易于调试,而且具有可扩展性. 缺点:  增加成本. 分层式结构究竟其优势何在? 1.开发人员可以只关注整个结构中的其中某一层

有意思的PHP代码块-面试经典

不使用PHP自带反转函数,将字符串反转. //不用自带函数将其反转 方法一 $str = "This is PHP"; $strArr = explode(' ',$str); $count = count($strArr)-1; for($i=$count;$i>=0;$i--){ $revStr .= $strArr[$i].' '; } echo $revStr; 方法二 $str = "This is PHP"; $strArr = explode('