面试经典150题【21-30】

news2024/11/19 20:19:38

文章目录

  • 面试经典150题【21-30】
    • 6.Z字形变换
    • 28.找出字符串中第一个匹配项的下标
    • 68.文本左右对齐
    • 392.判断子序列
    • 167.两数之和
    • 11.盛最多水的容器
    • 15.三数之和
    • 209.长度最小的子数组
    • 3.无重复字符的最长子串
    • 30.串联所有单词的子串

面试经典150题【21-30】

6.Z字形变换

对于“LEETCOD”且参数为3的时候,3代表有三行需要创建三个res数组
在这里插入图片描述

class Solution {
    public String convert(String s, int numRows) {
        if(numRows < 2) return s;
        List<StringBuilder> rows = new ArrayList<StringBuilder>();
        for(int i = 0; i < numRows; i++) rows.add(new StringBuilder());  //将数组创建且填充完成
        int i = 0, flag = -1;
        for(char c : s.toCharArray()) {
            rows.get(i).append(c);
            if(i == 0 || i == numRows -1) flag = - flag;  //如果到了最上面或最下面,则方向进行调转。
            i += flag;  //i决定下一个字母写到第几行
        }
        StringBuilder res = new StringBuilder();
        for(StringBuilder row : rows) res.append(row);
        return res.toString();

    }
}

28.找出字符串中第一个匹配项的下标

Sunday算法。
偏移表的作用是存储每一个在 模式串 中出现的字符,在 模式串 中出现的最右位置到尾部的距离 +1+1+1,例如 aab:

a 的偏移位就是 len(pattern)-1 = 2
b 的偏移位就是 len(pattern)-2 = 1
其他的均为 len(pattern)+1 = 4
在这里插入图片描述
要不就是移动到已有的(在Pianyi数组中),要不就是全部移动(移动nSize+1)

public class LC28 {
    static int strStr(String haystack,String needle){
        int hSize=haystack.length();
        int nSize=needle.length();
        HashMap<Character,Integer> pianyi=new HashMap<Character, Integer>();
        for(int i=0;i<needle.length();i++){
            //建立偏移表
            pianyi.put(needle.charAt(i),nSize-i);
        }

        //遍历
        int i=0;
        while(i<=hSize-nSize){
            //判断是否成功
            if(haystack.substring(i,i+nSize).equals(needle)) return i;
            else{
                //判断是否越界
                if(i+nSize > hSize-1) return -1;
                else{
                    if(pianyi.containsKey(haystack.charAt(i+nSize))){
                        //匹配,考虑往后移动几下
                        //取最后的下一位字母,来判断应该偏移几位。这样偏移了以后,就满足他离最后还差几位。
                        i+=pianyi.get(haystack.charAt(i+nSize));

                    }else{
                        i+=nSize+1; //不匹配,连这个字母也跳过
                    }
                }

            }
        }
        return-1;
    }

    public static void main(String[] args) {
        String haystack = "w222sadbutsad", needle = "sad";
        System.out.println(strStr(haystack,needle));

    }
}

68.文本左右对齐

模拟题
在这里插入图片描述
三种情况:
1.当前行是最后一行:单词左对齐,且单词之间应只有一个空格,在行末填充剩余空格;
2.当前行不是最后一行,且只有一个单词:该单词左对齐,在行末填充空格;
3.当前行不是最后一行,且不只一个单词。

public class LC68 {
    @Test
    public void test(){
        String[] words= {"This", "is", "an", "example", "of", "text", "justification."};
        int maxWidth=16;
        List<String> strings = fullJustify(words, maxWidth);
        for(String s1:strings){
            System.out.println(s1);
        }

    }

    public List<String> fullJustify(String[] words, int maxWidth) {
        List<String> ans = new ArrayList<String>();
        int right = 0, n = words.length;
        while (true) {
            int left = right; // 当前行的第一个单词在 words 的位置
            int sumLen = 0; // 统计这一行单词长度之和
            // 循环确定当前行可以放多少单词,注意单词之间应至少有一个空格
            while (right < n && sumLen + words[right].length() + right - left <= maxWidth) {
                sumLen += words[right++].length();
            }

            // 当前行是最后一行:单词左对齐,且单词之间应只有一个空格,在行末填充剩余空格
            if (right == n) {
                StringBuilder sb = join(words, left, n, " ");
                sb.append(blank(maxWidth - sb.length()));
                ans.add(sb.toString());
                return ans;
            }

            int numWords = right - left;
            int numSpaces = maxWidth - sumLen;

            // 当前行只有一个单词:该单词左对齐,在行末填充剩余空格
            if (numWords == 1) {
                StringBuffer sb = new StringBuffer(words[left]);
                sb.append(blank(numSpaces));
                ans.add(sb.toString());
                continue;
            }

            // 当前行不只一个单词
            int avgSpaces = numSpaces / (numWords - 1);
            int extraSpaces = numSpaces % (numWords - 1);
            StringBuffer sb = new StringBuffer();
            sb.append(join(words, left, left + extraSpaces + 1, blank(avgSpaces + 1))); // 拼接额外加一个空格的单词
            sb.append(blank(avgSpaces));
            sb.append(join(words, left + extraSpaces + 1, right, blank(avgSpaces))); // 拼接其余单词
            ans.add(sb.toString());
        }
    }
    // blank 返回长度为 n 的由空格组成的字符串
    public String blank(int n) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < n; ++i) {
            sb.append(' ');
        }
        return sb.toString();
    }

    // join 返回用 sep 拼接 [left, right) 范围内的 words 组成的字符串
    public StringBuilder join(String[] words, int left, int right, String sep) {
        StringBuilder sb = new StringBuilder(words[left]);
        for (int i = left + 1; i < right; ++i) {
            sb.append(sep);
            sb.append(words[i]);
        }
        return sb;
    }
}

#125.验证回文串

先把所有字母放到一个大字符串里(全部放小写字母),然后进行双指针的比较或直接比reverse也行
Character.isLetterOrDigit(ch) //判断是否为数字或字母
Character.toLowerCase(ch) //转小写

392.判断子序列

子序列和子串不一样。
“abc”是"ahbgdc"的子序列

167.两数之和

在这里插入图片描述
可以用双指针,缩减搜索空间。或者空间复杂度高一点做一个哈希表,每次读取了元素之后存到哈希表里。
return new int[]{hashMap.get(target-numbers[i])+1,i+1}

11.盛最多水的容器

在这里插入图片描述
求法就是双指针,面积就是底乘高。height[i]小就i++, height[j]小就j–;
若向内 移动短板 ,水槽的短板min(h[i],h[j]) 可能变大,因此下个水槽的面积 可能增大 。
若向内 移动长板 ,水槽的短板 min(h[i],h[j])​ 不变或变小,因此下个水槽的面积 一定变小

15.三数之和

在这里插入图片描述
先定一个first,然后就是求两数之和,双指针。注意不要重复的数字。

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        int n = nums.length;
        Arrays.sort(nums);
        List<List<Integer>> ans = new ArrayList<List<Integer>>();
        // 枚举 a
        for (int first = 0; first < n; ++first) {
            // 优化1 : 设 s = nums[first] + nums[first+1] + nums[first+2],如果 s >
            // 0,由于数组已经排序,后面无论怎么选,选出的三个数的和不会比 s 还小,所以只要 s > 0 就可以直接 break 外层循环了。
            if (first + 2 < n && nums[first] + nums[first + 1] + nums[first + 2] > 0) {
                return ans;
            }
            // 优化2 : 当nums[i] + nums[length - 1] + nums[length - 2] < 0 时,
            // nums[i]不可能符合条件,i++
            if (nums[first] + nums[n - 1] + nums[n - 2] < 0) {
                continue;
            }

            // 枚举的数字需要与上一个不同
            if (first > 0 && nums[first] == nums[first - 1]) {
                continue;
            }
            int third = n - 1;
            // 定义 b+c的目标位target
            int target = -nums[first];
            // 枚举b
            for (int second = first + 1; second < n; second++) {
                // 枚举数字需要与上一个不同
                if (second > first + 1 && nums[second] == nums[second - 1]) {
                    continue;
                }
                // 两数之和, 对于每一个second,枚举c
                while (second < third && nums[second] + nums[third] > target) {
                    --third;
                }
                // 重合了就退出循环
                if (second == third)
                    break;
                if (nums[second] + nums[third] == target) {
                    List<Integer> list = new ArrayList<Integer>();
                    list.add(nums[first]);
                    list.add(nums[second]);
                    list.add(nums[third]);
                    ans.add(list);
                }
            }
        }
        return ans;
    }
}

209.长度最小的子数组

在这里插入图片描述
正常的话要考虑两个东西,一个是找不到则答案输出为0,还有是因为是Min函数,要考虑ans的初始值。
但是也可以用一个三目运算符搞定。

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int i=0,sum=0,len=0;
        for(int j=0;j<nums.length;j++){
            sum+=nums[j];
            while(sum>=target){
                len= len==0? (j-i+1) :Math.min(len,j-i+1);
                sum-=nums[i++];
            }
        }
        return len;

    }
}

找不到答案,说明target太大,走不进while循环里。
只要大了,就取当前长度(j-i+1) 与 len 做比较。

3.无重复字符的最长子串

在这里插入图片描述
用set

public class LC3 {
    public int lengthOfLongestSubstring(String s) {
        if(s.length() ==0)  return 0;
        Set<Character> c1=new HashSet<Character>();
        int left=0,maxStr=0;
        for(int i=0;i<s.length();i++){
            while(c1.contains(s.charAt(i))){
                //因为有abcaad这种情况。所以应该删一次. 并且要将if改为while
                //移除的是最左边的元素,但是while判断里的是 i元素。
                c1.remove(s.charAt(left));
                left++;
            }
            maxStr=Math.max(maxStr,i-left+1);
            c1.add(s.charAt(i));

        }
        return maxStr;

    }
}

用hash

public class LC3 {
    public int lengthOfLongestSubstring(String s) {
        if(s.isEmpty())  return 0;
        Map<Character,Integer> map=new HashMap<>();
        int maxStr=0,left=0;
        for(int i=0;i<s.length();i++){
            if(map.containsKey(s.charAt(i))){
                //肯定是发生了abca这种,所以要把left从a变到b
                //left=map.get(s.charAt(i))+1;
                //如果遇到abba呢,会造成指针回跳,所以要修改
                //+1应该在括号里,因为有zmmuyrz的情况。答案应该是muyrz五个数。
                //一般都是走后面的情况,防止指针回跳加了个Max(left
                left=Math.max(left,map.get(s.charAt(i))+1);
            }
            map.put(s.charAt(i),i);
            maxStr=Math.max(maxStr,i-left+1);
        }
        return maxStr;

    }
}

30.串联所有单词的子串

这个滑动窗口太硬了,还是直接暴力吧。用一个hashMap来记录每个单词出现的次数。
在这里插入图片描述

class Solution {
    public List<Integer> findSubstring(String s, String[] words) {
        List<Integer> res = new ArrayList<Integer>();
        int wordNum = words.length;
        if (wordNum == 0) {
            return res;
        }
        int wordLen = words[0].length();
        // HashMap1 存所有单词
        HashMap<String, Integer> allWords = new HashMap<String, Integer>();
        for (String w : words) {
            int value = allWords.getOrDefault(w, 0);
            allWords.put(w, value + 1);
        }
        // 遍历所有子串
        for (int i = 0; i < s.length() - wordNum * wordLen + 1; i++) {
            // HashMap2 存当前扫描的字符串含有的单词
            HashMap<String, Integer> hasWords = new HashMap<String, Integer>();
            int num = 0;
            // 判断该子串是否符合
            while (num < wordNum) {
                String word = s.substring(i + num * wordLen, i + (num + 1) * wordLen);
                // 判断该单词在 HashMap1 中
                if (allWords.containsKey(word)) {
                    int value = hasWords.getOrDefault(word, 0);
                    hasWords.put(word, value + 1);
                    // 判断当前单词的 value 和 HashMap1 中该单词的 value
                    if (hasWords.get(word) > allWords.get(word)) {
                        break;
                    }
                } else {
                    break;
                }
                num++;
            }
            // 判断是不是所有的单词都符合条件
            if (num == wordNum) {
                res.add(i);
            }
        }
        return res;
    }

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1469496.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

五种多目标优化算法(MOBA、NSWOA、MOJS、MOAHA、MOPSO)性能对比(提供MATLAB代码)

一、5种多目标优化算法简介 多目标优化算法是用于解决具有多个目标函数的优化问题的一类算法。其求解流程通常包括以下几个步骤: 1. 定义问题:首先需要明确问题的目标函数和约束条件。多目标优化问题通常涉及多个目标函数,这些目标函数可能存在冲突,需要在不同目标之间进…

udp服务器【Linux网络编程】

目录 一、UDP服务器 1、创建套接字 2、绑定套接字 3、运行 1&#xff09;读取数据 2&#xff09;发送数据 二、UDP客户端 创建套接字&#xff1a; 客户端不用手动bind 收发数据 处理消息和网络通信解耦 三、应用场景 1、服务端执行命令 2、Windows上的客户端 3…

DiceCTF 2024 -- pwn

baby-talk 题目给了 Dockerfile&#xff0c;但由于笔者 docker 环境存在问题启动不起来&#xff0c;所以这里用虚拟机环境做了&#xff08;没错&#xff0c;由于不知道远程 glibc 版本&#xff0c;所以笔者远程也没打通&#xff09;笔者本地环境为 glibc 2.31-0ubuntu9.9。然后…

Shell grep命令练习题

目录 1含有“48“字符串的行的总数 2显示含有“48“字符串的所有行的行号 3精确匹配只含有“48”字符串的行 4抽取代码为484和483的城市位置 5显示使行首不是4或8 6显示含有九月份(Sept)的行 7显示以K开头&#xff0c;以D结尾的所有代码 8显示头两个是大写字母&#xff0c;中间…

规则持久化(Sentinel)

规则持久化 基于Nacos配置中心实现推送 引入依赖 <dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-datasource-nacos</artifactId> </dependency> 流控配置文件 [{"resource":"/order/flow",…

《Docker 简易速速上手小册》第6章 Docker 网络与安全(2024 最新版)

文章目录 6.1 Docker 网络概念6.1.1 重点基础知识6.1.2 重点案例&#xff1a;基于 Flask 的微服务6.1.3 拓展案例 1&#xff1a;容器间的直接通信6.1.4 拓展案例 2&#xff1a;跨主机容器通信 6.2 配置与管理网络6.2.1 重点基础知识6.2.2 重点案例&#xff1a;配置 Flask 应用的…

【Java程序设计】【C00302】基于Springboot的校园失物招领管理系统(有论文)

基于Springboot的校园失物招领管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的校园失物招领网站&#xff0c;本系统有管理员以及用户二种角色权限&#xff1b; 系统整体功能有&#xff1a;操作日志管理、…

Escalate_Linux靶机详解(1)

Escalate_Linux靶机详解&#xff08;1&#xff09; 一&#xff0c;信息收集 首先扫描存活主机 目标地址&#xff1a;192.168.236.131 使用nmap扫描保存为linux.nmap 2&#xff0c;HTTP探测 发现开放了80端口http 打开站点是apache的默认站点 默认页面&#xff0c;尝试对w…

PyTorch概述(六)---View

Tensor.view(*shape)-->Tensor 返回一个新的张量同之前的张量具有相同的数据&#xff0c;但是具有不同的形状&#xff1b;返回的张量同之前的张量共享相同的数据&#xff0c;必须具有相同数目的元素&#xff0c;可能具有不同的形状&#xff1b;对于经过view操作的张量&…

Android 内存优化内存泄漏处理

一:匿名内部类/非静态内部类 匿名内部类的泄漏原因&#xff1a;匿名内部类会隐式地持有外部类的引用.当外部类被销毁时&#xff0c;内部类并不会自动销毁&#xff0c;因为内部类并不是外部类的成员变量&#xff0c; 它们只是在外部类的作用域内创建的对象&#xff0c;所以内部…

《艾尔登法环 黄金树幽影》是什么?Mac电脑怎么玩《艾尔登法环》艾尔登法环下载

全体起立&#xff0c;《艾尔登法环 》最新DLC《黄金树幽影》将在6月21日发布&#xff0c;steam售价198元&#xff0c;现在就可以预订了。宫崎英高在接受FAMI通的采访时表示&#xff0c;新DLC的体量远超《黑暗之魂》和《血源诅咒》资料片。好家伙&#xff0c;别人是把DLC续作&am…

28V270V航空交直流线缆:满足飞机对高质量电气连接的需求

28V/270V航空交直流线缆&#xff1a;航空业的“神经系统” 在现代航空业中&#xff0c;无论是飞机、直升机还是其他飞行器&#xff0c;都离不开一种重要的设备&#xff0c;那就是航空28V/270V航空交直流线缆。航空28V/270V航空交直流线缆是飞行器上的电气系统的重要组成部分&am…

【操作系统】

计算机操作系统 计算机是如何让用户得到好的体验什么是操作系统&#xff08;OS&#xff09;操作系统如何管理 计算机是如何让用户得到好的体验 计算机系统是由计算机硬件和软件组成的。用户使用计算机&#xff0c;比如在文本文件填写内容&#xff0c;通过邮箱发送邮件&#xf…

RabbitMq:什么是RabbitMq? ①

一、RabbitMq定位 RabbitMq是一个基于消息订阅发布的一款消息中间件。 二、技术原理 核心概念 server&#xff1a;又称broker&#xff0c;接受客户端连接&#xff0c;实现AMQP实体服务。缓存代理&#xff0c;Kafka集群中的一台或多台服务器统称broker.connection&#xff1a;…

Python中回调函数的理解与应用

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站零基础入门的AI学习网站~。 目录 前言 回调函数的概念 回调函数的基本用法 回调函数的实现方式 1 使用函数 2 使用类方法 3 使用类实…

Web性能优化-详细讲解与实用方法-MDN文档学习笔记

Web性能优化 查看更多学习笔记&#xff1a;GitHub&#xff1a;LoveEmiliaForever MDN中文官网 性能优良的网站能够提高访问者留存和用户满意度&#xff0c;减少客户端和服务器之间传输的数据量可降低各方的成本 不同的业务目标和用户需求需要不同的性能度量&#xff0c;要提高…

pthread_cond_timedwait()函数

绝对时间&#xff1a;相对于1970年1月1日0时0分0秒 相对时间&#xff1a;相对于当前时间&#xff0c;如sleep(3);相对于当前&#xff0c;过3s.

mac下使用jadx反编译工具

直接执行步骤&#xff1a; 1.创建 jadx目录 mkdir jadx2.将存储库克隆到目录 git clone https://github.com/skylot/jadx.git 3. 进入 jadx目录 cd jadx 4.执行编译 等待片刻 ./gradlew dist出现这个就代表安装好了。 5.最后找到 jadx-gui 可执行文件&#xff0c;双击两下…

解决easyExcel模板填充时转义字符\{xxx\}失效

正常我们在使用easyExcel进行模板填充时&#xff0c;定义的变量会填充好对应的实际数据&#xff0c;未定义的变量会被清空&#xff0c;但是如果这个未定义的变量其实是模板的一部分&#xff0c;那么清空了就出错了。 在这张图里&#xff0c;上面的是模板填充后导出的文件&…

【Linux基础】vim、常用指令、组管理和组权限

Linux基础 1、目录结构2、vi和vim3、常用指令运行级别找回密码帮助指令时间日期指令搜索查找文件目录操作磁盘管理指令压缩和解压缩 4、组管理和组权限用户操作指令权限 1、目录结构 Linux的文件系统是采用级层式的树状目录结构&#xff0c;在此结构中的最上层是根目录“/”&a…