算法学习day19

news2024/9/24 10:20:04

一、通过删除字母匹配到字符字典中的最大值

给你一个字符串 s 和一个字符串数组 dictionary ,找出并返回 dictionary 中最长的字符串,该字符串可以通过删除 s 中的某些字符得到。

如果答案不止一个,返回长度最长且字母序最小的字符串。如果答案不存在,则返回空字符串。

输入:s = "abpcplea", dictionary = ["ale","apple","monkey","plea"]
输出:"apple"
思路:

遍历字符字典中的字符串,找到s串的子串,然后计算长度;

t串的长度大于res的长度,更新res;

t串的长度==res串的长度并且t串的字母序是靠前的,更新res;

注意:

使用String类中的compareTo()方法

返回值是整型,它是先比较对应字符的大小(ASCII码顺序),如果第一个字符和参数的第一个字符不等,结束比较,返回他们之间的长度差值,如果第一个字符和参数的第一个字符相等,则以第二个字符和参数的第二个字符做比较,以此类推,直至比较的字符或被比较的字符有一方结束。

代码:
class Solution {
    public String findLongestWord(String s, List<String> dictionary) {
        String res = "";
        for (String str : dictionary) {
            int i = 0;
            int j = 0;
            while (i < s.length() && j < str.length()) {
                if (s.charAt(i) == str.charAt(j)) {
                    j++;
                }
                i++;
            }
            if (j == str.length()) {
                if ((str.length() > res.length() || str.length() == res.length() && str.compareTo(res) < 0)) {
                    // 说明是子串 然后判断长度
                    res = str;
                }
            }
        }
        return res;
    }
}

二、最长特殊序列II

输入: strs = ["aba","cdc","eae"]
输出: 3
输入: strs = ["aaa","aaa","aa"]
输出: -1
题意:

给定字符串列表 strs ,返回其中 最长的特殊序列 的长度。如果最长特殊序列不存在,返回 -1 。

最长的特殊序列:该序列为某字符串 独有的子序列(即不能是其他字符串的子序列)

思路:

就是判断每一个字符串是不是其它字符串的子串,如果是的话,该字符串的最长特殊序列的长度为0;如果都不是的话,那么最长特殊序列的长度为str.length();

代码:
class Solution {
    public int findLUSlength(String[] strs) {
        int max = -1;
        for (int i = 0; i < strs.length; i++) {
            boolean flag = true;
            String t = strs[i];
            for (int j = 0; j < strs.length; j++) {
                if (i != j) {
                    String s = strs[j];
                    System.out.println("t: "+t+" s: "+s+"是否为子串:"+isSonStr(t,s));
                    if (isSonStr(t, s)) {
                        flag = false;
                    }
                }
            }
            if (flag)
                max = Math.max(max, strs[i].length());
        }
        return max;
    }

    public boolean isSonStr(String t, String s) {
        int i = 0;
        int j = 0;
        while (i < t.length() && j < s.length()) {
            if (t.charAt(i) == s.charAt(j)) {
                i++;
            }
            j++;
        }
        if (i == t.length())
            return true;
        return false;
    }
}
疑惑:

如果是aaa,aaa,aa。当进行判断字符串aaa是不是最长特殊序列的时候。先和aaa比较,发现是子串,flag直接为false;就不用和后面的aa进行比较了(尽管比较返回结果为true);

只要它是剩下字符串中其中一个的子串,就直接flag=false;

三、加一

给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。

最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。

你可以假设除了整数 0 之外,这个整数不会以零开头。

输入:digits = [1,2,3]
输出:[1,2,4]
解释:输入数组表示数字 123。

代码十分巧妙:如果该位置是9的话,那么就把它变成0。(数组的其他位置还会发生变化,需要继续遍历,直到不==9,返回)

如果不是9的话,就直接+1并且return digits;因为此时数组其他位置上已经不会变化了,直接返回数组就行。

最后如果还没有return,那么就要在最开始进一位

代码:
class Solution {
    public int[] plusOne(int[] digits) {
        int size=digits.length;
        for(int i=size-1;i>=0;i--){
            if(digits[i]==9){
                digits[i]=0;
            }else{
                digits[i]++;
                return digits;
            }
        }
        //如果代码执行到这里 说明还没有return掉 遇到999这种情况
        int[] arr=new int[digits.length+1];
        arr[0]=1;
        return arr;
    }
}

四、字符串相乘

如何避免越界的情况:

之前我使用int类型的变量去累加每一位上相乘的结果,因此会越界异常。

每一位置上的数字使用数组存储,然后再用字符串将每一个位置上的数字拼接起来。

思路:

1.首先创建一个长度为len1+len2的数组,用于存放每一位上的数。m位数*n位数的结果最多是(m+n)位数

2.使用双重循环给数组的每一个位置上赋值。int multi=x*y+arr[i+j+1]; arr[i+j+1]=multi%10;

arr[i+j]=multi/10; i+j+1是根据i,j的大小决定的,并且表示的是multi个位上的数字。multi是x*y的乘积加上上一次相乘结果的进位。i+j+1是进位。

注意:

最后使用StringBuilder拼接的时候,首位可能为0(比如说33*30=999 只有三位数 但是数组的空间是4),要考虑到这种情况

代码:
//会涉及到很大的数 超出int的范围
class Solution {
    public String multiply(String num1, String num2) {
        //如果出现0 直接返回0
        if(num1.equals("0")||num2.equals("0"))return "0";
        //其他情况
        int len1=num1.length();
        int len2=num2.length();
        int[] res=new int[len1+len2];//len1位数*len2位数 结果最多会有(len1+len2)位数
        for(int i=len1-1;i>=0;i--){
            int value1=num1.charAt(i)-'0';
            for(int j=len2-1;j>=0;j--){
                int value2=num2.charAt(j)-'0';
                int multi=value1*value2+res[i+j+1];
                res[i+j+1]=multi%10;
                res[i+j]+=multi/10;
            }
        }
        StringBuilder sb=new StringBuilder();
        for(int i=0;i<res.length;i++){
            if(i==0&&res[i]==0)continue;
            sb.append(res[i]);//拼接每一个数字
        }
        return sb.toString();
    }
}

五、累加数(回溯+剪枝)

累加数 是一个字符串,组成它的数字可以形成累加序列。

一个有效的 累加序列 必须 至少 包含 3 个数。除了最开始的两个数以外,序列中的每个后续数字必须是它之前两个数字之和。

给你一个只包含数字 '0'-'9' 的字符串,编写一个算法来判断给定输入是否是 累加数 。如果是,返回 true ;否则,返回 false 。

说明:累加序列里的数,除数字 0 之外,不会 以 0 开头,所以不会出现 1, 2, 03 或者 1, 02, 3 的情况。101 这样也可以

回溯算法:

1.返回值:boolean 参数:String num(字符串)、int count(数字的个数)、int startIndex(遍历的起始位置)、int prev(前一个数)、int prevprev(前两个数)

2.终止条件:当startIndex>=num.length()的时候,说明遍历结束了。此时要判断count是否大于2,如果超过两个数字,就说明字符串中存在三个数字,符合x1+x2=x3这样的规律

3.单层递归逻辑:for循环中,每次根据遍历的位置计算当前数字的值。然后根据条件判断是否继续遍历(条件为:count>=2 然后current>prev+prevprev 或者current<prev+prevprev)。如果满足条件,就终止了(遍历到下一层自动终止了)

代码:
class Solution {
    public boolean isAdditiveNumber(String num) {
        return dfs(num,0,0,0,0);
    }
    public boolean dfs(String num,int count,int startIndex,long prev,long pprev){
        //终止条件
        if(startIndex>=num.length()){
            return count>2;
        }
        //单层递归逻辑
        long cur=0;
        for(int i=startIndex;i<num.length();i++){
            //剪枝1:如果碰到0开头的数字 直接return false;
            if(i>startIndex&&num.charAt(startIndex)=='0')return false;

            char ch=num.charAt(i);
            int number=ch-'0';
            cur=cur*10+number;//当前的数字
            
            if(count>=2){
                long sum=prev+pprev;
                if(cur>sum){
                    return false;
                }else if(cur<sum){
                    continue;
                }
            }
            //如果count<2或者满足条件 就需要继续遍历
            boolean flag=dfs(num,count+1,i+1,cur,prev);
            if(flag)return true;
        }
        return false;
    }
}

六、z字形变换

将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。

比如输入字符串为 "PAYPALISHIRING" 行数为 3 时,排列如下:

P   A   H   N
A P L S I I G
Y   I   R

之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"PAHNAPLSIIGYIR"

思路:

使用List<StringBuilder>来存储每一行的字符串,最后将每一行的字符串拼接起来返回。

在遍历每一个字符串的字符的同时,把它加到对应的行中。(行是从上往下依次递增,如果在第一行或者最后一行就要转变方向 往下是++ 往上是--)

代码:

class Solution {
    public String convert(String s, int numRows) {
        //如果按照一行变换的话 直接返回
        if(numRows==1)return s;
        //创建存储行的集合
        List<StringBuilder> rows=new ArrayList<>();
        //初始化
        for(int i=0;i<Math.min(s.length(),numRows);i++){
            rows.add(new StringBuilder());
        }
        //控制方向的变量
        boolean up=false;
        int curRow=0;
        for(char ch:s.toCharArray()){
            rows.get(curRow).append(ch);//某一行进行拼接
            if(curRow==0||curRow==numRows-1){
                up=!up;
            }
            curRow+=up?1:-1;
        }
        StringBuilder res=new StringBuilder();
        for(StringBuilder sb:rows){
            res.append(sb);
        }
        return res.toString();
    }
}

七、回文子串类问题(二维dp)

1.dp[i][j]:a.从i->j这个范围内是否是回文子串。b.或者i->j里面最大回文子串的长度。

2.递推公式:

a.如果str.charAt(i)==str.charAt(j)。如果j-i<=1,dp[i][j]=true;如果j-i>1,dp[i][j]是否是回文子串需要看dp[i+1][j-1];

b.如果str.charAt(i)==str.charAt(j)。dp[i][j]=dp[i+1][j-1]+2; 如果不相等,dp[i][j]=Math.max(dp[i][j-1],dp[i+1][j])

八、最大回文数乘积()

给定一个整数 n ,返回 可表示为两个 n 位整数乘积的 最大回文整数 。因为答案可能非常大,所以返回它对 1337 取余 。

输入:n = 2
输出:987
解释:99 x 91 = 9009, 9009 % 1337 = 987

9009是2位数整数乘积的最大回文整数。

思路:

1.根据n的大小得出最大的n位数

2.从最大的n位数从大到小依次构建相应的回文数

3.如果回文数可以由两个n位数相乘得来,那么就return 回文数%1337

代码:
class Solution {
    public int largestPalindrome(int n) {
        if(n==1)return 9;
        //找到n位数字可以表示的最大值
        int max=(int)Math.pow(10,n)-1;
        for(int i=max;i>=0;i--){
            long num=i;
            long t=i;
            //找数的最大值
            while(t!=0){
                num=num*10+t%10;
                t/=10;
            }
            //找最大的回文数
            for(long j=max;j*j>=num;j--){
                if(num%j==0)return (int)(num%1337);    
            }
        }
        return -1;
    }
}

九、数字的补数(位运算)

对整数的二进制表示取反(0 变 1 ,1 变 0)后,再转换为十进制表示,可以得到这个整数的补数。

例如,整数 5 的二进制表示是 "101" ,取反后得到 "010" ,再转回十进制表示得到补数 2 。

位运算:(异或)

000^111=111 (异或),只有当相同的位置上的数字不同时,得1;否则,得0;

思路:

这道题要我们求补数,就是让我们将num上的每一位有效值(不算前面补的0)都和1做异或运算,那么有多少位有效数字呢?就是num/2 可以被除几次。每除一次,就拼接一次1(二进制上的1)

代码:
class Solution {
    public int findComplement(int num) {
        int temp=num,c=0;
        //首先看temp有多少位
        while(temp>0){
            temp>>=1;//右移一位
            c=(c<<1)+1;//c每次都左移一位
        }
        return num^c;
    }
}

十、汉明距离(位运算)

两个整数之间的 汉明距离 指的是这两个数字对应二进制位不同的位置的数目。

给你两个整数 x 和 y,计算并返回它们之间的汉明距离。

输入:x = 1, y = 4
输出:2
解释:
1   (0 0 0 1)
4   (0 1 0 0)
思路:

把xy异或之后 有多少个1 就有多少个二进制位不同的位置。(只有不同的二进制位异或后才会得1)。然后计算1的个数就可以。

(z&1)==1 count++;z>>>1;

代码:
class Solution {
    public int hammingDistance(int x, int y) {
        //异或一下 如果找为1的最小距离
        int c=x^y;
        int start=0,end=0;
        int count=0;
        while(c!=0){
            if((c&1)==1)count++;
            c>>>=1;//因为c可能是0 >>>不考虑符号位
        }
        return count;
    }
}

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

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

相关文章

花几千上万学习Java,真没必要!(二十六)

1、成员内部类&#xff1a; package internalclass.com; //在Java中&#xff0c;成员内部类&#xff08;也称为非静态内部类&#xff09;是定义在另一个类&#xff08;外部类&#xff09;内部的类。 //成员内部类可以访问外部类的所有成员&#xff08;包括私有成员&#xff09…

【计算机网络】网络层——IPv4地址(个人笔记)

学习日期&#xff1a;2024.7.24 内容摘要&#xff1a;IPv4地址&#xff0c;分类编址&#xff0c;子网&#xff0c;无分类编址 IPv4地址概述 在TCP/IP体系中&#xff0c;IP地址是一个最基本的概念&#xff0c;IPv4地址就是给因特网上的每一台主机的每一个接口分配一个在全世界…

ASP.NET Web Api 使用 EF 6,DateTime 字段如何取数据库服务器当前时间

前言 在做数据库设计时&#xff0c;为了方便进行数据追踪&#xff0c;通常会有几个字段是每个表都有的&#xff0c;比如创建时间、创建人、更新时间、更新人、备注等&#xff0c;在存储这些时间时&#xff0c;要么存储 WEB 服务器的时间&#xff0c;要么存储数据库服务器的时间…

Java之数组应用-冒泡排序-二分查找

冒泡排序 冒泡(Bubble Sort)排序是一种简单排序算法&#xff0c;它通过依次比较交换两个相邻元素实现功能。每一次冒泡会让至少一个元素移动到它应该在的位置上&#xff0c;这样 n 次冒泡就完成了 n 个数据的排序工作。 这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”…

python实现图像缩放算法

图像缩放算法 1.最近邻插值图像缩放算法详解算法步骤Python 实现详细解释 优缺点2.双线性插值图像缩放算法详解算法步骤Python 实现详细解释 优缺点3.双三次插值图像缩放算法详解算法步骤Python 实现详细解释 优缺点 1.最近邻插值图像缩放算法详解 最近邻插值&#xff08;Near…

【网络】计算机网络基础——计算机网络背景和发展、认识网络协议、OSI七层模型、TCP/IP四层模型、网络的传输

文章目录 Linux网络1. 计算机网络背景和发展2. 认识网络协议3. OSI七层模型3.1 物理层3.2 数据链路层3.3 网络层3.4 传输层3.5 会话层3.6 表示层3.7 应用层 4. TCP/IP四层模型5. 网络的传输 Linux网络 1. 计算机网络背景和发展 开始的计算机都是独立模式&#xff08;计算机之间…

与众不同的社交体验:Facebook的新功能与新变化

在快速变化的社交媒体领域&#xff0c;Facebook不断引入创新功能和变化&#xff0c;以满足用户日益增长的需求&#xff0c;并提供与众不同的社交体验。从增强现实到数据隐私&#xff0c;Facebook的新功能和更新正在塑造一个全新的社交平台。本文将深入探讨这些新功能和变化&…

3W单声道关断模式音频功率放大器AD4150B

前言&#xff1a; 国产功放介绍 NS4890C 2.4W 单声道AB类音频放大器 AD4150B 3W单声道关断模式音频功率放大器 参考价格0.3元 产品概述 AD4150B是一款单声道带关断模式&#xff0c;桥式音频功率放大器。在5.5V工作电压时&#xff0c;平均驱动功率为&#xff1a;3W&#xff08…

计算机网络之http和https的区别(外加http详解)

http协议和各种协议之间的关系 1、DNS解析&#xff0c;获取到访问服务器的IP 2、HTTP生成请求报文请求&#xff0c;请求访问页面资源 3、TCP协议将报文切割成一份一份报文段后&#xff0c;以可靠的方式进行传输 4、IP协议边搜索边中转&#xff0c;将这些数据包传输给接受方…

关于c#的简单应用三题

#region 输入一个正整数&#xff0c;求1~这个数的阶乘 public static void Factorial(int a) { int result 1; for (int i 1; i < a; i) { result result * i; } Console.WriteLine(result); } #endregion #region 一个游戏&#…

详解Stable Diffusion 原理图

参考英文文献&#xff1a;The Illustrated Stable Diffusion – Jay Alammar – Visualizing machine learning one concept at a time. 在这个Stable Diffusion模型的架构图中&#xff0c;VAE&#xff08;变分自编码器&#xff09;模型对应的是图中的 E 和 D 部分。 具体来说…

keystone学习小结2

简介 通过源码 官方文档 进行学习 官方文档 架构 identity 提供user和group的鉴权及数据 可以用这些数据处理增删改查的请求 这些服务在某些情况也可以托管在授权的服务中&#xff0c;有认证任务时&#xff0c;授权的服务会执行认证的任务&#xff0c;而不会把这些转发到…

SuperMap GIS基础产品FAQ集锦(20240715)

一、SuperMap iDesktopX 问题1&#xff1a;想问一下&#xff0c;线数据更改粗细和颜色&#xff0c;他只能保存到地图中吗&#xff1f;我希望能修改源数据&#xff0c;但是保存不了&#xff1f; 11.1.1 【问题原因】简单数据集不支持保存风格。 【解决办法】入需保存风格&…

SAP中途增加批次管理提示:库存在工厂级别已经存在。

SAP中途增加批次管理提示&#xff1a;库存在工厂级别已经存在。 在这种情况&#xff0c;将需要启用批次管理功能的物料主数据进行出库&#xff0c;通过移动类型201&#xff08;562&#xff09;进行出库&#xff0c;然后再修改物料主数据&#xff0c;当成功启用物料主数据的批次…

前置-Linux相关知识速记

linux Linux命令大全 [!IMPORTANT] chown-chmod-ls-chgrp-cdpwd-mkdir-rmdir-cp-rm-mv-cat-tac-nl-more-less-head-tail 应用领域 通常服务器使用 LAMP&#xff08;Linux Apache MySQL PHP&#xff09;或 LNMP&#xff08;Linux Nginx MySQL PHP&#xff09;组合。 目前…

700.二叉搜索树的搜索

给定二叉搜索树&#xff08;BST&#xff09;的根节点 root 和一个整数值 val。 你需要在 BST 中找到节点值等于 val 的节点。 返回以该节点为根的子树。 如果节点不存在&#xff0c;则返回 null 。 示例 1: 输入&#xff1a;root [4,2,7,1,3], val 2 输出&#xff1a;[2,1,3]…

SmartX 超融合 vs vSAN 8:数据库场景下的性能对比

此前&#xff0c;我们以 vSAN 7 为例&#xff0c;对比了 SmartX 与 VMware 超融合在快照、缓存、I/O 路径上的技术差异&#xff0c;及其带来的性能影响。不同于 vSAN 7&#xff0c;vSAN 8 引入了快速存储架构 ESA&#xff08;Express Storage Architecture&#xff09;&#xf…

SpringCloud------Seata(分布式事务)

分布式事务产生原因 CAP定理(一致性、可用性、分区容错性) BASE理论 解决思想 Seata 三个角色

【操作系统】线程池的底层逻辑解析及实现

目录 线程池一、线程池是什么二、底层线程池 ThreadPoolExecutor三、实现线程池四、标准库中的线程池Executors 线程池 一、线程池是什么 在我们频繁的创建线程时或销毁线程时,都会进行系统调度从而占用系统资源,虽然创建线程/销毁线程的开销不是很大,但架不住量多,进而我们该…

photoshop学习笔记——选区

选区工具快捷键&#xff1a;M shift M 切换 矩形/椭圆选区工具 基本用法 选区框选出的地方被激活&#xff08;其后进行的操作&#xff0c;仅在选区中生效&#xff09; 选区工具选择后&#xff08;以矩形选区为例&#xff09; 按下鼠标左键拖动&#xff0c;画出一块矩形区…