阿俊带你用Kotlin刷算法(五)

本系列通过JavaKotlin这两种语言来解决力扣上面的算法题,由于本人算法菜鸟一枚,可能部分题目并不是最优题解,希望能和各位大神共同讨论~

阿俊带你用Kotlin刷算法(一)

阿俊带你用Kotlin刷算法(二)

阿俊带你用Kotlin刷算法(三)

阿俊带你用Kotlin刷算法(四)

项目的GitHub:Algorithm

最长公共前缀(Longest Common Prefix)

难度:简单

链接:Longest Common Prefix

代码

Java

/*** Created by TanJiaJun on 2021/7/5.* 14. 最长公共前缀(Longest Common Prefix)* 难度:简单** @see <a href="https://leetcode-cn.com/problems/longest-common-prefix/">Longest Common Prefix</a>*/
class LongestCommonPrefix {public static void main(String[] args) {// 示例一System.out.print("示例一:");String[] firstStrs = {"flower", "flow", "flight"};System.out.println(longestCommonPrefix(firstStrs));System.out.print("\n");// 示例二System.out.print("示例二:");String[] secondStrs = {"dog", "racecar", "car"};System.out.println(longestCommonPrefix(secondStrs));}/*** 横向扫描* <p>* 时间复杂度:O(mn),其中m是字符串数组strs中的字符串平均长度,n是字符串数组strs的长度。* 空间复杂度:O(1),使用的空间复杂度为常数。** @param strs 字符串数组* @return 最长公共前缀字符串*/private static String longestCommonPrefix(String[] strs) {if (strs == null) {// 如果是空的字符串数组,就不运行下面的逻辑了,直接返回空字符串return "";}String result = strs[0];for (int i = 1, length = strs.length; i < length; i++) {// 得到当前两个字符串的公共前缀result = getLongestCommonPrefix(result, strs[i]);if (result.isEmpty()) {// 如果result是空字符串,说明当前两个字符串不存在公共前缀,证明该字符串数组中所有字符串之间不存在公共前缀,// 所以跳出循环,不再遍历剩下的字符串,返回空字符串break;}}return result;}/*** 得到两个字符串的公共前缀** @param firstStr  第一个字符串* @param secondStr 第二个字符串* @return 两个字符串的最长公共前缀字符串,要注意的是,如果没有的话,就返回空字符串*/private static String getLongestCommonPrefix(String firstStr, String secondStr) {// 得到两个字符串的最小长度int minLen = Math.min(firstStr.length(), secondStr.length());int index = 0;// 遍历两个字符串的字符while (index < minLen && firstStr.charAt(index) == secondStr.charAt(index)) {// 如果索引小于最短长度,并且当前两个字符串的字符相同,就增加索引值index++;}// 截取两个字符串的公共前缀,要注意的是,如果找不到公共前缀会返回空字符串return firstStr.substring(0, index);}}

Kotlin

import kotlin.math.min/*** Created by TanJiaJun on 2021/7/24.* 14. 最长公共前缀(Longest Common Prefix)* 难度:简单** @see <a href="https://leetcode-cn.com/problems/longest-common-prefix/">Longest Common Prefix</a>*/
object LongestCommonPrefixKotlin {@JvmStaticfun main(args: Array<String>) {// 示例一print("示例一:")val firstStrs = arrayOf("flower", "flow", "flight")println(longestCommonPrefix(firstStrs))print("\n")// 示例二print("示例二:")val secondStrs = arrayOf("dog", "racecar", "car")println(longestCommonPrefix(secondStrs))}/*** 横向扫描** 时间复杂度:O(mn),其中m是字符串数组strs中的字符串平均长度,n是字符串数组strs的长度。* 空间复杂度:O(1),使用的空间复杂度为常数。** @param strs 字符串数组* @return 最长公共前缀字符串*/private fun longestCommonPrefix(strs: Array<String>): String {var result: String = strs[0]for (i in 1 until strs.size) {// 得到当前两个字符串的公共前缀result = getLongestCommonPrefix(result, strs[i])if (result.isEmpty()) {// 如果result是空字符串,说明当前两个字符串不存在公共前缀,证明该字符串数组中所有字符串之间不存在公共前缀,// 所以跳出循环,不再遍历剩下的字符串,返回空字符串break}}return result}/*** 得到两个字符串的公共前缀** @param firstStr 第一个字符串* @param secondStr 第二个字符串* @return 两个字符串的最长公共前缀字符串,要注意的是,如果没有的话,就返回空字符串*/private fun getLongestCommonPrefix(firstStr: String, secondStr: String): String {// 得到两个字符串的最小长度val minLen = min(firstStr.length, secondStr.length)var index = 0// 遍历两个字符串的字符while (index < minLen && firstStr[index] == secondStr[index]) {// 如果索引小于最短长度,并且当前两个字符串的字符相同,就增加索引值index++}// 截取两个字符串的公共前缀,要注意的是,如果找不到公共前缀会返回空字符串return firstStr.substring(0, index)}}

时间复杂度

O(mn),其中m是字符串数组strs中的字符串平均长度,n是字符串数组strs的长度。

空间复杂度

O(1),使用的空间复杂度为常数

题解

我们可以通过横向扫描来解决这道算法题。大概流程为依次遍历字符串数组中的每一个字符串,得到两个字符串的公共前缀,当遍历完所有字符串后,就能得到该字符串数组中的最长公共前缀。要注意的是,如果在尚未遍历完字符串数组的情况下,公共前缀返回为空字符串,说明当前两个字符串不存在公共前缀,证明该字符串数组中所有字符串之间不存在公共前缀,所以就不需要继续遍历剩下的字符串,返回空字符串作为结果。

三数之和(3Sum)

难度:中等

链接:3Sum

代码

Java

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;/*** Created by TanJiaJun on 2021/7/25.* 15. 三数之和(3Sum)* 难度:中等** @see <a href="https://leetcode-cn.com/problems/3sum/">3Sum</a>*/
class ThreeSum {public static void main(String[] args) {// 示例一System.out.print("示例一:");int[] firstNums = {-1, 0, 1, 2, -1, -4};System.out.println(threeSum(firstNums));System.out.print("\n");// 示例二System.out.print("示例二:");int[] secondNums = {};System.out.println(threeSum(secondNums));System.out.print("\n");// 示例三System.out.print("示例三:");int[] thirdNums = {0};System.out.println(threeSum(thirdNums));}/*** 双指针* <p>* 时间复杂度:O(n^2),数组遍历为O(n),双指针遍历为O(n),总体为O(n)*O(n)=O(n^2)* 空间复杂度:O(1),使用的空间复杂度为常数。** @param nums 整型数组* @return 结果集合*/private static List<List<Integer>> threeSum(int[] nums) {List<List<Integer>> result = new ArrayList<>();if (nums == null || nums.length < 3) {// 如果数组为空或者其长度小于3,就返回空集合return result;}// 将数组进行排序Arrays.sort(nums);for (int i = 0, length = nums.length; i < length - 2; i++) {if (nums[i] > 0) {// 如果当前起始元素大于0,由于数组已经进行排序,所以最小的元素都大于0,// 证明三数之和肯定大于0,跳出循环,返回空集合break;}if (i > 0 && nums[i] == nums[i - 1]) {// 去除重复结果:从第二个元素开始,如果当前元素和上一个元素相等,那么会得到相同的结果,跳出当前循环continue;}// 左指针:初始左指针为当前索引的下一个元素int left = i + 1;// 右指针:初始右指针为数组的最后一个元素int right = length - 1;// 遍历,使左右指针靠近while (left < right) {// 将当前元素、左指针对应的元素和右指针对应的元素相加int sum = nums[i] + nums[left] + nums[right];if (sum < 0) {// 如果结果小于0,证明需要更大的元素,左指针往右移动一个元素left++;} else if (sum > 0) {// 如果结果大于0,证明需要更小的元素,右指针往左移动一个元素right--;} else {// 如果等于0,就把结果放进集合result.add(Arrays.asList(nums[i], nums[left], nums[right]));while (left < right && nums[left] == nums[left + 1]) {// 去除重复结果:如果当前左指针对应的元素和下一个(右边)元素相等,就把左指针往右边移动多一个元素left++;}// 左指针往右边移动一个元素left++;while (left < right && nums[right] == nums[right - 1]) {// 去除重复结果:如果当前右指针对应的元素和下一个(左边)元素相等,就把右指针往左边移动多一个元素right--;}// 右指针往左边移动一个元素right--;}}}return result;}}

Kotlin

import java.util.*/*** Created by TanJiaJun on 2021/7/25.* 15. 三数之和(3Sum)* 难度:中等** @see <a href="https://leetcode-cn.com/problems/3sum/">3Sum</a>*/
object ThreeSumKotlin {@JvmStaticfun main(args: Array<String>) {// 示例一print("示例一:")val firstNums = intArrayOf(-1, 0, 1, 2, -1, -4)println(threeSum(firstNums))print("\n")// 示例二print("示例二:")val secondNums = intArrayOf()println(threeSum(secondNums))print("\n")// 示例三print("示例三:")val thirdNums = intArrayOf(0)println(threeSum(thirdNums))}/*** 双指针* <p>* 时间复杂度:O(n^2),数组遍历为O(n),双指针遍历为O(n),总体为O(n)*O(n)=O(n^2)* 空间复杂度:O(1),使用的空间复杂度为常数。** @param nums 整型数组* @return 结果集合*/private fun threeSum(nums: IntArray): List<List<Int>> =mutableListOf<List<Int>>().apply {if (nums.size < 3) {// 如果数组为空或者其长度小于3,就返回空集合return@apply}// 将数组进行排序Arrays.sort(nums)for (i in 0 until nums.size - 2) {if (nums[i] > 0) {// 如果当前起始元素大于0,由于数组已经进行排序,所以最小的元素都大于0,// 证明三数之和肯定大于0,跳出循环,返回空集合break}if (i > 0 && nums[i] == nums[i - 1]) {// 去除重复结果:从第二个元素开始,如果当前元素和上一个元素相等,那么会得到相同的结果,跳出当前循环continue}// 左指针:初始左指针为当前索引的下一个元素var left = i + 1// 右指针:初始右指针为数组的最后一个元素var right = nums.size - 1// 遍历,使左右指针靠近while (left < right) {// 将当前元素、左指针对应的元素和右指针对应的元素相加val sum = nums[i] + nums[left] + nums[right]when {// 如果结果小于0,证明需要更大的元素,左指针往右移动一个元素sum < 0 -> left++// 如果结果大于0,证明需要更小的元素,右指针往左移动一个元素sum > 0 -> right--else -> {// 如果等于0,就把结果放进集合add(listOf(nums[i], nums[left], nums[right]))while (left < right && nums[left] == nums[left + 1]) {// 去除重复结果:如果当前左指针对应的元素和下一个(右边)元素相等,就把左指针往右边移动多一个元素left++}// 左指针往右边移动一个元素left++while (left < right && nums[right] == nums[right - 1]) {// 去除重复结果:如果当前右指针对应的元素和下一个(左边)元素相等,就把右指针往左边移动多一个元素right--}// 右指针往左边移动一个元素right--}}}}}}

时间复杂度

O(n2)**,数组遍历为**O(n)**,双指针遍历为**O(n)**,总体为**O(n)*O(n)=O(n2)

空间复杂度

O(1),使用的空间复杂度为常数

题解

我们可以通过双指针来解决这道算法题。大概流程为遍历该数组,初始左指针设置为当前元素的下一个(右边)元素,初始右指针设置为数组的最后一个元素。通过遍历,使左右指针靠近,如果结果小于0,证明需要更大的元素,左指针往右移动一个元素;如果结果大于0,证明需要更小的元素,右指针往左移动一个元素;如果等于0,就把结果放进集合。要注意的是,有三个地方需要去除重复结果,如下所示:

  1. 从第二个元素开始,如果当前元素和上一个元素相等,那么会得到相同的结果,跳出当前循环。

  2. 如果当前左指针对应的元素和下一个(右边)元素相等,就把左指针往右边移动多一个元素。

  3. 如果当前右指针对应的元素和下一个(左边)元素相等,就把右指针往左边移动多一个元素。

我的GitHub:TanJiaJunBeyond

Android通用框架:Android通用框架

我的掘金:谭嘉俊

我的简书:谭嘉俊

我的CSDN:谭嘉俊

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

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

相关文章

瑞芯微第二代8nm高性能AIOT平台 RK3576 详细介绍

RK3576处理器 RK3576瑞芯微第二代8nm高性能AIOT平台&#xff0c;它集成了独立的6TOPS&#xff08;Tera Operations Per Second&#xff0c;每秒万亿次操作&#xff09;NPU&#xff08;神经网络处理单元&#xff09;&#xff0c;用于处理人工智能相关的任务。此外&#xff0c;R…

teknoparrot命令行启动游戏

官方github cd 到teknoparrot解压目录 cd /d E:\mn\TeknoParrot2_cp1\GameProfiles启动游戏 TeknoParrotUi.exe --profile游戏配置文件游戏配置文件位置/UserProfiles,如果UserProfiles文件夹里没有那就在/GameProfiles,在配置文件里将游戏路径加入之间,或者打开模拟器设置 …

基于ACM32 MCU的两轮车充电桩方案,打造高效安全的电池管理

随着城市化进程的加快、人们生活水平的提高和节能环保理念的普及&#xff0c;越来越多的人选择了电动车作为代步工具&#xff0c;而两轮电动车的出行半径较短&#xff0c;需要频繁充电&#xff0c;因此在城市中设置两轮车充电桩就非常有必要了。城市中的充电桩不仅能解决两轮车…

python+django+vue房屋租赁系统 8gwmf

房屋租赁系统在设计与实施时&#xff0c;采取了模块性的设计理念&#xff0c;把相似的系统的功能整合到一个模组中&#xff0c;以增强内部的功能&#xff0c;减少各组件之间的联系&#xff0c;从而达到减少相互影响的目的。如房源信息、预约信息、求租信息模块等[12]。 管理员后…

springcloud:3.7测试线程池服务隔离

服务提供者【test-provider8001】 Openfeign远程调用服务提供者搭建 文章地址http://t.csdnimg.cn/06iz8 相关接口 测试远程调用&#xff1a;http://localhost:8001/payment/index 服务消费者【test-consumer-resilience4j8004】 Openfeign远程调用消费者搭建 文章地址http://t…

数据库学习案例20240306-oracle数据库连接类故障trace

1 数据库连接类故障TRACE 故障现象 客户端tnsping ipv6:1521 提示Permission denied&#xff0c;但是在本机是可以链接的。 查看数据库netstat -tunlp|grep 1521 TCP 地址&#xff1a;1521 TCP 不全的IPV6&#xff1a;1521 没有tcp6协议出现。 故障分析 客户端sqlnet.o…

[Redis]——数据一致性,先操作数据库,还是先更新缓存?

目录 一、操作缓存和数据库时有三个问题需要考虑&#xff1a; 1.删除缓存还是更新缓存&#xff1f; 2.如何保证缓存与数据库的操作同时成功或失效 3.先操作缓存还是先操作数据库&#xff08;多线程并发问题&#xff09; 二、 缓存更新的最佳策略 一、操作缓存和数据库时有…

C#使用自定义的方法设计堆栈类

目录 1.首先创建一个名为Clist的类 2.接下来创建一个名为CStack的类 3.最后使用CStack类和Push方法来添加和遍历堆栈数据 4.运行结果 本实例展示了如何使用C#创建一个带有Push方法和Clist类的CStack类&#xff0c;并如何在其中添加和遍历堆栈数据。 1.首先创建一个名为Cli…

深度学习-多层神经网络

文章目录 多层深度神经网络一.黑箱&#xff1a;深层神经网络的不可解释性二.多元神经网络&#xff1a; 层与 h ( z ) h(z) h(z)三.激活函数 多层深度神经网络 从单层到多层是神经网络发展史上的重大变化&#xff0c;层的增加彻底将神经网络的性能提升到了另一个高度&#xff0…

「Vue3系列」Vue3 Axios详解

文章目录 一、Vue3 Axios二、Vue3 Axios 请求配置项三、Axios 响应结构四、Axios 拦截器请求拦截器响应拦截器拦截器的移除拦截器的应用场景 五、相关链接 一、Vue3 Axios 在 Vue 3 中&#xff0c;你可以使用 axios 来执行 AJAX 请求。axios 是一个流行的基于 Promise 的 HTTP…

Java面向对象详解以及示例解析

Java面向对象详解 文章目录 Java面向对象详解 面向对象编程&#xff08;Object-Oriented Programming&#xff0c;简称OOP&#xff09;是一种计算机编程模型。其核心在于围绕数据或对象来组织软件设计&#xff0c;而非仅仅依赖于功能和逻辑。这种编程方式更专注于对象与对象之间…

设计模式之依赖倒转原则

目录 1、 基本介绍 2、 应用实例 3、 依赖关系传递的三种方式 (1) 接口传递 (2) 构造方法传递 (3) setter方式传递 4、 注意事项和细节 1、 基本介绍 依赖倒转原则(Dependence Inversion Principle)是指&#xff1a; 高层模块不应该依赖低层模块&#xff0c;二者都应该依…

文字悬浮下划线动态效果

概览 此篇文章主要介绍文字悬浮下划线的动画效果&#xff0c;主要有从左往右和从中间至两边扩散两种动态效果 一. 从左往右 示例代码如下 <!DOCTYPE html> <html><head><meta charset"utf-8"><meta name"viewport" content…

【C语言】C语言编程进阶:异常处理与程序稳定性全攻略

1. 概述 异常处理又称异常错误处理&#xff0c;它提供了处理程序运行时出现任何意外或异常情况的方法。异常处理通常是防止未知错误的发生所采取的处理措施&#xff0c;对于某一类型的错误&#xff0c;异常处理应该提供相应的处理方法。例如&#xff0c;在设计程序时&#xff…

AI智商排名:Claude-3首次突破100

用挪威门萨&#xff08;智商测试题&#xff09;中 35 个问题对chatGPT等人工智能进行了测试&#xff1a; ChatGPT 对ChatGPT进行了两次挪威门萨测试&#xff0c;在 35 个问题中&#xff0c;它平均答对了 13 个&#xff0c;智商估计为 85。 测试方法 每个人工智能都接受了两次…

<商务世界>《第5课 重组、托管是什么?》

1 托管 1.1 案例 2020年10月&#xff0c;国资委决定&#xff0c;由中国宝武钢铁集团有限公司对中国中钢集团有限公司进行托管&#xff0c;这就意味着中钢集团由一个副部级的央企管理了&#xff0c;虽然级别没有变动&#xff0c;但是他的好多决策都不用先汇报给国资委了&#…

MATLAB知识点:循环语句的经典练习题

​讲解视频&#xff1a;可以在bilibili搜索《MATLAB教程新手入门篇——数学建模清风主讲》。​ MATLAB教程新手入门篇&#xff08;数学建模清风主讲&#xff0c;适合零基础同学观看&#xff09;_哔哩哔哩_bilibili 节选自​第4章&#xff1a;MATLAB程序流程控制 下面我们来看…

springmvc的使用方法及运行原理

Spring MVC 是 Spring 框架中用于开发 Web 应用程序的一部分&#xff0c;它基于 MVC&#xff08;Model-View-Controller&#xff09;设计模式&#xff0c;提供了一种灵活且强大的方式来构建 Web 应用。 运行原理&#xff1a; 客户端发送请求&#xff1a;浏览器向服务器发送 H…

贷齐乐错误的waf引起的SQL注入漏洞复现

君衍. 一、环境介绍1、第一道WAF2、第二道WAF 二、环境部署1、模拟源码2、连接数据库源码3、数据库创建4、测试 三、源码分析1、模拟WAF2、注入思路3、PHP下划线特性4、完成假设 四、联合查询注入1、测试回显字段2、爆出库名3、爆出表名4、爆出表下的列名4、爆出flag 一、环境介…

CleanMyMac X4.14.7永久免费Mac电脑清理和优化软件

CleanMyMac X 是一款功能强大的 Mac 清理和优化软件&#xff0c;适合以下几类人群使用&#xff1a; 需要定期清理和优化 Mac 的用户&#xff1a;随着时间的推移&#xff0c;Mac 设备上可能会积累大量的无用文件、缓存和垃圾&#xff0c;导致系统运行缓慢。CleanMyMac X 的智能扫…