717. 1比特与2比特字符 / 18. 四数之和 / 22. 括号生成

2023-11-01 05:40

本文主要是介绍717. 1比特与2比特字符 / 18. 四数之和 / 22. 括号生成,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

717. 1比特与2比特字符【简单题】【每日一题】

思路:

  1. 从前往后遍历bits数组,如果当前元素是1,那么由于第二种字符无论是10还是11,都是以1开头,所以可以肯定当前元素和它的下一个元素构成第二种字符,直接 i+= 2;bits数组只有0和1,不是1的话那必然是0,而只有第一种字符以0开头,且只占一位,所以此时如果当前元素已经是最后一位了,那么此时最后一位可以构成第一种字符,于是直接返回true,如果不是最后一位,那么i++。
  2. 如果可以跳出for循环,说明此时最后一位无法构成字符,于是返回false。

代码:

class Solution {public boolean isOneBitCharacter(int[] bits) {int len = bits.length,i = 0;while (i<len){if (bits[i] == 1){i+=2;}else {if (i == len-1){return true;}else {i++;}}}return false;}
}

用时:

在这里插入图片描述


18. 四数之和【中等题】

思路:

  1. 与三数之和类似,本题的四数之和先固定第一个数,再固定第二个数,然后双指针表示后两个数,实现思路就是,先排序,数组自左向右依次变大,于是,当前两个数固定之后,后两个数与前两个数这四数之和如果大于target,则右指针左移,如果小于target,则左指针右移,如果等于target,则说明这四个数就是我们要找的四个数,将其添加到ans列表中,同时题目中要求四元组不能相同,因此可以用hashset对其进行去重,做法是,将ans定义为hashset格式,然后返回new
    ArrayList(ans)。
  2. 这个题重点不在解题思路,在如何剪枝,按照如上思路写出来的,用时 116ms,击败5%,我一看时间不对啊,这也太长了,我就去看题解,结果发现题解也是这个思路,但是它剪枝了,我就想,那我也去剪剪试试,此时还没看题解代码。
  3. 第一次修改,增加了固定第一个数之后,如果前四个数大于target,则直接退出第一层for循环;如果前四个数等于target,则将这四个数添加到答案ans中,并继续下一次第一层for循环;如果第一个数和后三个数之和小于target,则继续下一次第一层for循环。增加了固定第二个数之后,如果前两个数与接下来数组中前两个数之和大于target,则直接退出第二层for循环;如果前两个数与接下来数组中后两个数之和小于target,则继续下一次第二层for循环。修改之后用时
    18ms ,还是没追上题解。
  4. 第二次修改,在第一次修改的基础上,增加了在第一层for循环的开始,先判断当i大于0时,当前i位置数与前一个位置数是否相等,如果相等,说明四元组中第一个数重复了,而当后3个数不变的情况下,如果第一个数重复必然会导致整个四元组的重复,因此跳过这个重复的数字,即继续下一次第一层for循环;同理在第二层for循环的开始,先判断当j>i+1时,当前j位置数是否与前一个位置数相等,如果相等,则跳过这个重复的数字,继续下一次第二层for循环。修改之后用时
    5ms ,还是没追上题解。
  5. 第三次修改,在第一次和第二次修改的基础上,增加了:对第三个和第四个数的去重,即在while循环中,如果遇到符合题意的四元组,则将其添加到ans中的同时,可以同时使用while循环对left和right位置的数进行去重,如果left位置和left+1位置的数相等,那么left++,如果right位置和right-1位置的数相等,那么right–;同时发现当四个数都进行去重之后,我就不用去hashset对四元组进行去重了,我现在的ans已经没有重复的四元组了,于是将ans修改为ArrayList形式的列表,最后返回ans;另外,在开头添加判断条件,当nums数组的长度小于4时,不可能有符合条件的四元组,此时直接返回空的ans。修改之后用时
    3ms ,还是没有追上题解。
  6. 第四次修改,其实第3次修改就是看了题解的代码改的,结果发现还是比它差了1ms,经过我又一次的观察,发现题解添加四个数字进list的方式不一样,
    题解用的是,ans.add(Arrays.asList(nums[i],nums[j],nums[left],nums[right]));
    而我用的是
    ans.add(new ArrayList(Arrays.asList(nums[i],nums[j],nums[left],nums[right])));
    就事实来说,题解的肯定更好一点,是我太菜了我不知道还可以这么写。

代码:
直接放第4版的代码了。

class Solution {public List<List<Integer>> fourSum(int[] nums, int target) {List<List<Integer>> ans = new ArrayList<>();int len = nums.length;if (len<4){return ans;}Arrays.sort(nums);for (int i = 0; i < len-3; i++) {if(i > 0 && nums[i] == nums[i-1]){continue;}long before4_1 = (long) nums[i]+nums[i+1]+nums[i+2]+nums[i+3];if (before4_1 > target){break;}else if (before4_1 == target){ans.add(Arrays.asList(nums[i],nums[i+1],nums[i+2],nums[i+3]));continue;}if ((long)nums[i]+nums[len-1]+nums[len-2]+nums[len-3] < target){continue;}for (int j = i+1; j < len-2; j++) {if(j > i+1 && nums[j] == nums[j-1]){continue;}int left = j+1,right = len-1;long pre = (long) nums[i]+nums[j],before4_2 = pre + nums[left]+nums[left+1];if (before4_2 > target){break;}if (pre +nums[right]+nums[right-1] < target){continue;}while (left<right){int cur = nums[left]+nums[right];if (pre+cur<target){left++;}else if (pre+cur>target){right--;}else {ans.add(Arrays.asList(nums[i],nums[j],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 ans;}
}

用时:

在这里插入图片描述


22. 括号生成【中等题】

思路:

  1. 我不知道这算动态规划还是算递归,但感觉跟青蛙跳台阶的题有相似之处。
  2. 定义hashset类型ans用来存储去重的答案,初值默认为一对儿括号。从2开始for循环遍历,到n结束(可以取到n),定义一个hashset类型temp来存储括号对数为i时可以生成的括号;遍历ans中的每一个括号组合,设遍历到的括号组合为str,那么依次在str的每一个元素后边插入一对括号(可以在整个str的前方插入括号,也可以在整个str的后方插入括号);将插入括号的新括号组合存入temp中;当ans中所有的括号组合都被遍历过之后,将ans更新为temp中的所有括号组合,并继续下一次关于
    i 的for循环。
  3. 当遍历完n之后,for循环退出,此时将ans转为ArrayList类型列表返回。
  4. 主要解题依据是,根据上一个n的括号组合,来求当前n的括号组合。

代码:

class Solution {public List<String> generateParenthesis(int n) {Set<String> ans = new HashSet<>();ans.add("()");for (int i = 2; i <= n; i++) {Set<String> temp = new HashSet<>();for (String str : ans){for (int j = 0; j < str.length(); j++) {temp.add(str.substring(0,j)+"()"+str.substring(j));}}ans = temp;}return new ArrayList<>(ans);}
}

用时:

在这里插入图片描述

这篇关于717. 1比特与2比特字符 / 18. 四数之和 / 22. 括号生成的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/320849

相关文章

Java利用docx4j+Freemarker生成word文档

《Java利用docx4j+Freemarker生成word文档》这篇文章主要为大家详细介绍了Java如何利用docx4j+Freemarker生成word文档,文中的示例代码讲解详细,感兴趣的小伙伴... 目录技术方案maven依赖创建模板文件实现代码技术方案Java 1.8 + docx4j + Fr

Java编译生成多个.class文件的原理和作用

《Java编译生成多个.class文件的原理和作用》作为一名经验丰富的开发者,在Java项目中执行编译后,可能会发现一个.java源文件有时会产生多个.class文件,从技术实现层面详细剖析这一现象... 目录一、内部类机制与.class文件生成成员内部类(常规内部类)局部内部类(方法内部类)匿名内部类二、

使用Jackson进行JSON生成与解析的新手指南

《使用Jackson进行JSON生成与解析的新手指南》这篇文章主要为大家详细介绍了如何使用Jackson进行JSON生成与解析处理,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 核心依赖2. 基础用法2.1 对象转 jsON(序列化)2.2 JSON 转对象(反序列化)3.

java中使用POI生成Excel并导出过程

《java中使用POI生成Excel并导出过程》:本文主要介绍java中使用POI生成Excel并导出过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录需求说明及实现方式需求完成通用代码版本1版本2结果展示type参数为atype参数为b总结注:本文章中代码均为

在java中如何将inputStream对象转换为File对象(不生成本地文件)

《在java中如何将inputStream对象转换为File对象(不生成本地文件)》:本文主要介绍在java中如何将inputStream对象转换为File对象(不生成本地文件),具有很好的参考价... 目录需求说明问题解决总结需求说明在后端中通过POI生成Excel文件流,将输出流(outputStre

C语言字符函数和字符串函数示例详解

《C语言字符函数和字符串函数示例详解》本文详细介绍了C语言中字符分类函数、字符转换函数及字符串操作函数的使用方法,并通过示例代码展示了如何实现这些功能,通过这些内容,读者可以深入理解并掌握C语言中的字... 目录一、字符分类函数二、字符转换函数三、strlen的使用和模拟实现3.1strlen函数3.2st

C/C++随机数生成的五种方法

《C/C++随机数生成的五种方法》C++作为一种古老的编程语言,其随机数生成的方法已经经历了多次的变革,早期的C++版本使用的是rand()函数和RAND_MAX常量,这种方法虽然简单,但并不总是提供... 目录C/C++ 随机数生成方法1. 使用 rand() 和 srand()2. 使用 <random

Flask 验证码自动生成的实现示例

《Flask验证码自动生成的实现示例》本文主要介绍了Flask验证码自动生成的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习... 目录生成图片以及结果处理验证码蓝图html页面展示想必验证码大家都有所了解,但是可以自己定义图片验证码

Python如何在Word中生成多种不同类型的图表

《Python如何在Word中生成多种不同类型的图表》Word文档中插入图表不仅能直观呈现数据,还能提升文档的可读性和专业性,本文将介绍如何使用Python在Word文档中创建和自定义各种图表,需要的... 目录在Word中创建柱形图在Word中创建条形图在Word中创建折线图在Word中创建饼图在Word

nginx生成自签名SSL证书配置HTTPS的实现

《nginx生成自签名SSL证书配置HTTPS的实现》本文主要介绍在Nginx中生成自签名SSL证书并配置HTTPS,包括安装Nginx、创建证书、配置证书以及测试访问,具有一定的参考价值,感兴趣的可... 目录一、安装nginx二、创建证书三、配置证书并验证四、测试一、安装nginxnginx必须有"-