《Java练习题》进阶练习题(五)
编程合集: https://www.cnblogs.com/jssj/p/12002760.html
前言:不仅仅要实现,更要提升性能,精益求精,用尽量少的时间复杂度和空间复杂度解决问题。
【程序88】
给定一个未排序的整数数组,找出其中没有出现的最小的正整数。
/**
* 给定一个未排序的整数数组,找出其中没有出现的最小的正整数。
*/
public class Subject88 {
public static void main(String[] args) {
int[] arrInt = new int[]{-1,-9,1,2,4,6,9,8};
int number = new Subject88().firstMissingPositive(arrInt);
System.out.println(number);
} public int firstMissingPositive(int[] nums) {
int n = nums.length; // 基本情况
int contains = 0;
for (int i = 0; i < n; i++) {
if (nums[i] == 1) {
contains++;
break;
}
}
if (contains == 0)
return 1; // nums = [1]
if (n == 1)
return 2; // 用 1 替换负数,0,
// 和大于 n 的数
// 在转换以后,nums 只会包含
// 正数
for (int i = 0; i < n; i++)
if ((nums[i] <= 0) || (nums[i] > n))
nums[i] = 1; // 使用索引和数字符号作为检查器
// 例如,如果 nums[1] 是负数表示在数组中出现了数字 `1`
// 如果 nums[2] 是正数 表示数字 2 没有出现
for (int i = 0; i < n; i++) {
int a = Math.abs(nums[i]);
// 如果发现了一个数字 a - 改变第 a 个元素的符号
// 注意重复元素只需操作一次
if (a == n)
nums[0] = - Math.abs(nums[0]);
else
nums[a] = - Math.abs(nums[a]);
} // 现在第一个正数的下标
// 就是第一个缺失的数
for (int i = 1; i < n; i++) {
if (nums[i] > 0)
return i;
} if (nums[0] > 0)
return n; return n + 1;
}
}
时间复杂度为 O(n)。
运行结果:
【程序89】
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。感谢 Marcos 贡献此图。
/**
* 【程序89】
* 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
* 上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。感谢 Marcos 贡献此图。
*/
public class Subject89 { public static void main(String[] args) {
int[] arrInt = new int[]{0,1,4,2,1,0,1,7,2,1,2,6};
int side = new Subject89().trap(arrInt);
System.out.println(side);
} public int trap(int[] height) {
int max = 0;
int side =0;
for (int i = 0; i < height.length ; i++) {
if(height[i] > max){
max = height[i];
side = i;
}
} int unit = 0;
//右边接收雨水量
unit = unit + trapRight(height,side);
//左边接受雨水量
unit = unit + trapLeft(height,side);
return unit;
} public int trapRight(int[] height,int side) {
int unit = 0;
int maxTmp = 0;
int sideTmp =0;
for (int i = height.length-1 ; i > side; i--) {
if(height[i] > maxTmp){
maxTmp = height[i];
sideTmp = i;
}
} //计算中间存在多少单位
unit = trapUnit(height,side,sideTmp);
if(maxTmp > 0 && sideTmp != height.length-1){
unit += trapRight(height,sideTmp);
}
return unit;
} public int trapLeft(int[] height,int side) {
int unit = 0;
int maxTmp = 0;
int sideTmp =0;
for (int i = 0 ; i < side; i++) {
if(height[i] > maxTmp){
maxTmp = height[i];
sideTmp = i;
}
}
//计算中间存在多少单位
unit = trapUnit(height, sideTmp,side);
if(maxTmp > 0 && sideTmp != 0) {
unit += trapLeft(height, sideTmp);
}
return unit;
} /**
* 计算中间可以存在多少单位雨水
* @param height
* @return
*/
public int trapUnit(int[] height,int left,int right){
int unit = 0;
if(right-left <= 1){
return unit;
} int low =0;
if(height[left] > height[right]){
low = height[right];
}else{
low = height[left];
} for (int i = left+1; i <= right-1; i++) {
unit = unit + (low - height[i]);
}
return unit;
}
}
时间复杂度为 O(n)。
运行结果:
【程序90】
给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。
/**
* 给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。
*/
public class Subject90 {
public static void main(String[] args) {
String num1 = "123";
String num2 = "456";
String nultiply = new Subject90().multiply(num1,num2);
System.out.println(nultiply);
}
public String multiply(String num1, String num2) {
if (num1.equals("0") || num2.equals("0")) {
return "0";
}
int[] res = new int[num1.length() + num2.length()];
for (int i = num1.length() - 1; i >= 0; i--) {
int n1 = num1.charAt(i) - '0';
for (int j = num2.length() - 1; j >= 0; j--) {
int n2 = num2.charAt(j) - '0';
int sum = (res[i + j + 1] + n1 * n2);
res[i + j + 1] = sum % 10;
res[i + j] += sum / 10;
}
} StringBuilder result = new StringBuilder();
for (int i = 0; i < res.length; i++) {
if (i == 0 && res[i] == 0) continue;
result.append(res[i]);
}
return result.toString();
}
}
时间复杂度为 O(MN)。
运行结果:
【程序91】
给定一个字符串(s) 和一个字符模式(p) ,实现一个支持'?'和'*'的通配符匹配。
'?' 可以匹配任何单个字符。
'*' 可以匹配任意字符串(包括空字符串)。
两个字符串完全匹配才算匹配成功。
/**
* 给定一个字符串(s) 和一个字符模式(p) ,实现一个支持'?'和'*'的通配符匹配。
* '?' 可以匹配任何单个字符。
* '*' 可以匹配任意字符串(包括空字符串)。
* 两个字符串完全匹配才算匹配成功。
*/
public class Subject91 {
public static void main(String[] args) {
String str1 = "abbabaaabababbaababbabbbbbabbbabb";
String str2 = "**aa*abb***";
System.out.println(new Subject91().isMatch(str1,str2));
} boolean isMatch(String str, String pattern) { int s = 0, p = 0, match = 0, starIdx = -1;
//遍历整个字符串
while (s < str.length()){
// 一对一匹配,两指针同时后移。
if (p < pattern.length() && (pattern.charAt(p) == '?' || str.charAt(s) == pattern.charAt(p))){
s++;
p++;
}
// 碰到 *,假设它匹配空串,并且用 startIdx 记录 * 的位置,记录当前字符串的位置,p 后移
else if (p < pattern.length() && pattern.charAt(p) == '*'){
starIdx = p;
match = s;
p++;
}
// 当前字符不匹配,并且也没有 *,回退
// p 回到 * 的下一个位置
// match 更新到下一个位置
// s 回到更新后的 match
// 这步代表用 * 匹配了一个字符
else if (starIdx != -1){
p = starIdx + 1;
match++;
s = match;
}
//字符不匹配,也没有 *,返回 false
else return false;
} //将末尾多余的 * 直接匹配空串 例如 text = ab, pattern = a*******
while (p < pattern.length() && pattern.charAt(p) == '*')
p++; return p == pattern.length();
}
}
时间复杂度为 O(TP)。
运行结果:
【程序92】
给定一个非负整数数组,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
你的目标是使用最少的跳跃次数到达数组的最后一个位置。
/**
* 给定一个非负整数数组,你最初位于数组的第一个位置。
* 数组中的每个元素代表你在该位置可以跳跃的最大长度。
* 你的目标是使用最少的跳跃次数到达数组的最后一个位置。
*/
public class Subject92 { public static void main(String[] args) {
int[] arrInt = new int[]{2,3,1,1,4,2,1};
System.out.println(new Subject92().jump(arrInt));
} public int jump(int[] nums) {
//小于等于1的都不需要跳
int lengths = nums.length;
if(lengths <= 1){
return 0;
}
int reach = 0; //当前能走的最远距离
int nextreach = nums[0];
int step = 0; //需要步数
for(int i = 0;i<lengths;i++){
//贪心算法核心:这一步是不是可以比上一步得到更多步数,可以则取最新的路线。
nextreach = Math.max(i+nums[i],nextreach);
if(nextreach >= lengths-1) return (step+1);
if(i == reach){
step++;
reach = nextreach;
}
}
return step;
}
}
时间复杂度为 O(n)。
运行结果:
【程序93】
给定一个没有重复数字的序列,返回其所有可能的全排列。
import java.util.ArrayList;
import java.util.List; /**
* 给定一个没有重复数字的序列,返回其所有可能的全排列。
*/
public class Subject93 {
public static void main(String[] args) {
int[] arrInt = new int[]{1,2,3};
List<List<Integer>> integerList1 = new Subject93().permute(arrInt);
System.out.println(integerList1);
} List<List<Integer>> integerList = new ArrayList<>();
List<Integer> integerListTmp = new ArrayList<>(); int index = -1; /**
* 就一步步实现呗
* @param nums
* @return
*/
public List<List<Integer>> permute(int[] nums) { List<Integer> numList = new ArrayList<>();
for (int i = 0; i < nums.length; i++) {
numList.add(nums[i]);
integerListTmp.add(nums[i]);
}
index = nums.length;
permute(numList);
return integerList;
} public void permute(List<Integer> numList) {
int sizes = numList.size();
if (sizes <= 0) {
return ;
}
for (int i = 0; i < sizes; i++) {
integerListTmp.set(index- sizes,numList.get(i));
if(sizes <= 1){
List<Integer> numListTmp0 = new ArrayList<>();
numListTmp0.addAll(integerListTmp);
integerList.add(numListTmp0);
return;
}
List<Integer> numListTmp = new ArrayList<>();
numListTmp.addAll(numList);
numListTmp.remove(i);
permute(numListTmp);
}
}
}
时间复杂度为 。
运行结果:
【程序94】
给定一个可包含重复数字的序列,返回所有不重复的全排列。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map; /**
* 给定一个可包含重复数字的序列,返回所有不重复的全排列。
*/
public class Subject94 {
public static void main(String[] args) {
int[] arrInt = new int[]{3,1,3,3};
List<List<Integer>> integerList1 = new Subject94().permuteUnique(arrInt);
System.out.println(integerList1);
} List<List<Integer>> integerList = new ArrayList<>();
List<Integer> integerListTmp = new ArrayList<>(); int index = -1; /**
* 使用排序后,
* 剪枝的方式实现。
* @param nums
* @return
*/
public List<List<Integer>> permuteUnique(int[] nums) {
List<Integer> numList = new ArrayList<>();
//排序
Arrays.sort(nums); for (int i = 0; i < nums.length; i++) {
numList.add(nums[i]);
integerListTmp.add(nums[i]);
}
index = nums.length;
permuteUnique(numList);
return integerList;
} public void permuteUnique(List<Integer> numList) {
int sizes = numList.size();
if (sizes <= 0) {
return ;
}
Map<Integer,Integer> map = new HashMap<>();
for (int i = 0; i < sizes; i++) {
Integer integer = map.get(index- sizes);
if(integer != null){
if(integer == numList.get(i)){ //多余的分支都剪掉
continue;
}else{
map.put(index- sizes,numList.get(i));
}
}else{
map.put(index- sizes,numList.get(i));
} if(integerListTmp.get(index- sizes) != numList.get(i)){
integerListTmp.set(index- sizes,numList.get(i));
}
if(sizes <= 1){
List<Integer> numListTmp0 = new ArrayList<>();
numListTmp0.addAll(integerListTmp);
integerList.add(numListTmp0);
return;
}
List<Integer> numListTmp = new ArrayList<>();
numListTmp.addAll(numList);
numListTmp.remove(i);
permuteUnique(numListTmp);
}
}
}
时间复杂度为 。
运行结果:
【程序95】
给定一个 n×n 的二维矩阵表示一个图像。
将图像顺时针旋转 90 度。
说明:
你必须在原地旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要使用另一个矩阵来旋转图像。
/**
* 给定一个 n×n 的二维矩阵表示一个图像。
* 将图像顺时针旋转 90 度。
* 说明:
* 你必须在原地旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要使用另一个矩阵来旋转图像。
*/
public class Subject95 {
public static void main(String[] args) {
int[][] arrInt = new int[][]{{1,2,3},{4,5,6},{7,8,9}};
new Subject95().rotate(arrInt);
System.out.println(arrInt);
} public void rotate(int[][] matrix) {
int n = matrix.length;
for (int i = 0; i < (n + 1) / 2; i ++) {
for (int j = 0; j < n / 2; j++) {
int temp = matrix[n - 1 - j][i];
matrix[n - 1 - j][i] = matrix[n - 1 - i][n - j - 1];
matrix[n - 1 - i][n - j - 1] = matrix[j][n - 1 -i];
matrix[j][n - 1 - i] = matrix[i][j];
matrix[i][j] = temp;
}
}
}
}
时间复杂度为 O(n^2)。
运行结果:
【程序96】
给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串。
示例:
输入: ["eat", "tea", "tan", "ate", "nat", "bat"],
输出:
[
["ate","eat","tea"],
["nat","tan"],
["bat"]
]
说明:
所有输入均为小写字母。
不考虑答案输出的顺序。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map; /**
* 给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串。
* 示例:
* 输入: ["eat", "tea", "tan", "ate", "nat", "bat"],
* 输出:
* [
* ["ate","eat","tea"],
* ["nat","tan"],
* ["bat"]
* ]
* 说明:
* 所有输入均为小写字母。
* 不考虑答案输出的顺序。
*/
public class Subject96 {
public static void main(String[] args) {
String[] strArr = new String[]{"eat", "tea", "tan", "ate", "nat", "bat"};
List<List<String>> listList = new Subject96().groupAnagrams(strArr);
System.out.println(listList);
} List<List<String>> listList = new ArrayList<>();
Map<String,List<String>> map = new HashMap<>();
public List<List<String>> groupAnagrams(String[] strs) {
for (int i = 0; i < strs.length; i++) {
char[] ch = strs[i].toCharArray();
String str = dealChar(ch);
if(map.get(str) == null){
List<String> list = new ArrayList<>();
list.add(strs[i]);
map.put(str,list);
}else{
List<String> list = map.get(str);
list.add(strs[i]);
}
} Iterator<Map.Entry<String, List<String>>> it=map.entrySet().iterator();
while(it.hasNext()){
Map.Entry<String, List<String>> entry=it.next();
listList.add(entry.getValue());
} return listList;
} public String dealChar(char[] ch) {
Arrays.sort(ch);
return new String(ch,0,ch.length);
}
}
时间复杂度为 O(nk)。
运行结果:
【程序97】
实现 pow(x, n) ,即计算 x 的 n 次幂函数。
-100.0 < x < 100.0
n 是 32 位有符号整数,其数值范围是 [?2^31, 2^31 ? 1] 。
import java.util.HashMap;
import java.util.Map; /**
* 实现 pow(x, n) ,即计算 x 的 n 次幂函数。
* -100.0 < x < 100.0
* n 是 32 位有符号整数,其数值范围是 [?2^31, 2^31 ? 1] 。
*/
public class Subject97 { public static void main(String[] args) {
double dou = new Subject97().myPow(1.13183,-2147483648);
System.out.println(dou);
} Map<Integer,Double> map = new HashMap<>(); public double myPow(double x, int n) {
double dou = 1.0; if(n > 0){
if(n < 10){
for (int i =0 ;i < n; i++){
dou = dou*x ;
}
}else{
map.put(1,x);
map.put(2,x*x);
map.put(4,x*x*x*x);
map.put(8,x*x*x*x*x*x*x*x); int index = 8;
while(index <= n/2 && index < 1073741824){
int tmp = index;
index = index*2;
map.put(index,map.get(tmp)* map.get(tmp));
} dou = map.get(index);
int surplus = n - index;
while(surplus > 0){
index = index/2;
if(surplus >= index){
dou = dou*map.get(index);
}else{
continue;
}
surplus = surplus - index;
if(index == 1){
break;
}
}
} }else if(n == 0){
return 1;
}else{
if(n > -10){
for (int i =0 ;i < -n; i++){
dou = dou*(1.0/x) ;
}
}else{
map.put(-1,1.0/x);
map.put(-2,(1.0/x)*(1.0/x));
map.put(-4,(1.0/x)*(1.0/x)*(1.0/x)*(1.0/x));
map.put(-8,(1.0/x)*(1.0/x)*(1.0/x)*(1.0/x)*(1.0/x)*(1.0/x)*(1.0/x)*(1.0/x)); int index = -8;
while(index >= n/2 ){
int tmp = index;
index = index*2;
map.put(index,map.get(tmp)* map.get(tmp));
} dou = map.get(index);
int surplus = n - index;
while(surplus < 0){
index = index/2;
if(surplus <= index){
dou = dou*map.get(index);
}else{
continue;
}
surplus = surplus - index;
if(index == -1){
break;
}
}
}
}
return dou;
}
}
时间复杂度为 O(n)。
运行结果:
以上题目均来自:https://leetcode-cn.com/ ,如果你热爱编码,热爱算法,该网站一定适合你。
《Java练习题》进阶练习题(五)的更多相关文章
- java语言进阶(五)_异常
第一章 异常 1.1 异常概念 异常 :指的是程序在执行过程中,出现的非正常的情况,最终会导致JVM的非正常停止. 在Java等面向对象的编程语言中,异常本身是一个类,产生异常就是创建异常对象并抛出了 ...
- 6、50道JAVA基础编程练习题跟答案
50道JAVA基础编程练习题 [程序1] 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 程序分析 ...
- 50道JAVA基础编程练习题
50道JAVA基础编程练习题 [程序1] 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子对数为多少? 程序分析 ...
- 50道JAVA基础编程练习题 - 题目
50道JAVA基础编程练习题[1]题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? [2]题目:判断 ...
- Java进阶(五)Java I/O模型从BIO到NIO和Reactor模式
原创文章,同步发自作者个人博客,http://www.jasongj.com/java/nio_reactor/ Java I/O模型 同步 vs. 异步 同步I/O 每个请求必须逐个地被处理,一个请 ...
- 【视频+图文】Java基础经典练习题(一)输出2-100之间的素数,及素数个数
目录 第一题:判断2-100之间有多少个素数,并输出所有素数. 1.视频讲解: 2.思路分析: 代码讲解:以i=4为例 4.为大家准备了彩蛋: 能解决题目的代码并不是一次就可以写好的 我们需要根据我们 ...
- 【视频+图文】Java经典基础练习题(三):输入3个整数,并将其由小到大输出
目录 一.视频讲解 二.思路分析 总结: 三.代码+详解+结果 四.彩蛋 能解决题目的代码并不是一次就可以写好的 我们需要根据我们的思路写出后通过debug模式找到不足再进行更改 多次测试后才可得到能 ...
- # 2019-2020-3 《Java 程序设计》第五周学习总结
2019-2020-3 <Java 程序设计>第五周知识总结 1.使用interface来定义一个接口.接口定义同类的定义类似,也是分为接口的声明和接口体,其中接口体由常量定义和方法定义两 ...
- 20155312 2016-2017-2 《Java程序设计》第五周学习总结
20155312 2016-2017-2 <Java程序设计>第五周学习总结 课堂笔记 十个基本类型 命令:ascii打印ascii值, od -tx1 Test.java用十六进制查看代 ...
- 20155333 2016-2017-2 《Java程序设计》第五周学习总结
20155333 2016-2017-2 <Java程序设计>第五周学习总结 教材学习内容总结 1.使用try.catch语法 与C语言中程序流程和错误处理混在一起不同,Java中把正常流 ...
随机推荐
- ubuntu 16.04上源码编译opengv | compile opengv on ubuntu 16.04
本文首发于个人博客https://kezunlin.me/post/1e5d14ee/,欢迎阅读! compile opengv on ubuntu 16.04 Series compile open ...
- 【01】主函数main
java和C#非常相似,它们大部分的语法是一样的,但尽管如此,也有一些地方是不同的. 为了更好地学习java或C#,有必要分清它们两者到底在哪里不同. 首先,我们将探讨主函数main. java的主函 ...
- 扛把子组2018092609-2 选题 Scrum立会报告+燃尽图 06
此作业的要求参见[https://edu.cnblogs.com/campus/nenu/2019fall/homework/8681] 一.小组情况组长:迟俊文组员:宋晓丽 梁梦瑶 韩昊 刘信鹏队名 ...
- cookies与session简介
一.session和cookie 简单来讲cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案. 同时我们也看到,由于采用服务器端保持状态的方案在客户端 ...
- python的reduce,map,zip,filter和sorted函数
一. reduce(function,Iterable),它的形式和map()函数一样.不过参数function必须有两个参数. reduce()函数作用是:把结果继续和序列的下一个元素做累积计 ...
- 在centos7上进行hadoop-3.1.2的伪分布搭建
第一步:配置网络(静态IP) vi /etc/sysconfig/network-scripts/ifcfg-ens33(网卡名称可能不同) 1. 修改: 将该配置文件中的ONBOOT=no修改为ye ...
- django-migrate一败再败
python3 manage.py makemigrations # 生成数据库迁移文件 python3 manage.py migrate # 迁移数据库 简简单单两条命令就完成了django的数据 ...
- python函数-函数对象
python函数-函数对象 实验室 当函数定义时,就类似a=1,以函数名为变量名 def zx(): pass print(zx) zx=21 print(zx) <function zx at ...
- 关于servlet报错和jsp中报关于servlet的错误
servlet-api是对servlet的支持,如果你导入别人的项目后出现servlet中的导包处出现关于javax.servlet.的错误,那么就是缺少这个包了.还有对jsp页面中的报错的支持. 下 ...
- ios中日期处理