11.28
1.力扣:和为零的 N 个不同整数(模拟)
解题思路:
:::danger
分析:题目给的一个参数为n,是需要返回的结果数组的长度,因此可以创建一个长度为n的数组,用来存放结果。这个题不限制数据,我们可以自定义数据,我们只需要刚好符合结果的数字即可
:::
思路:图中可以以n/2为对称轴填写,形成一个数轴,对称轴的位置为0,但是需要考虑到一个情况如果n为偶数的时候的对称轴如何存放。因此首先遍历数组的一半,填入的数字的最大值为n/2。本题中的数字为2,
结果为 -2 -1 0 1 2 。
限制循环的时候如果n为偶数,其实是可以直接填充完毕的,最后只需要给奇数的最中间的值切换成0即可。
代码实现
class Solution {
public int[] sumZero(int n) {
int[] ans=new int[n];
if(n==1){
ans[0]=0;
return ans;
}
int a=n/2;
for(int i=0;i<n/2;i++){
ans[i]=-a;
ans[n-i-1]=a;
a--;
}
if(n%2!=0){ans[n/2]=0;}
return ans;
}
}
2.力扣:最大平均值和的分组(动态规划)
3.AcWing:01背包问题(动态规划)
解题思路
12.4 (力扣周赛)
4. 回环句(字符串)
解题思路
:::danger
给定的一个sentence没一个单词首尾应该一样,整个句子形成一个环
:::
代码实现(暴力)
:::warning
思路为判断空格,定一个一个结果为true,遍历每一个空格,如果空格前后字母不相等结果为false,最后判断收尾是否相等。
:::
class Solution {
public boolean isCircularSentence(String sentence) {
int n = sentence.length();
for(int i = 0;i < n;i++){
if(sentence.charAt(i) == ' '){
if(sentence.charAt(i + 1) != sentence.charAt(i - 1)){
return false;
}
}
}
return sentence.charAt(0) == sentence.charAt(n - 1);
}
}
代码实现(字符串分割)
:::warning
将字符串通过空格分割出来并存到String类型的数组中,需要遍历第一个字符串数组的最后一个元素和第二个的第一个元素即可,最后判断第一个和最后一个。
:::
class Solution {
public boolean isCircularSentence(String sentence) {
String[] split = sentence.split(" ");
int len = split.length;
if (split[len-1].charAt(split[len-1].length()-1) != split[0].charAt(0)) {
return false;
}
for(int i = 0; i < len-1;i++ ) {
System.out.println(i);
if (split[i].charAt(split[i].length()-1) != split[i+1].charAt(0)) {
return false;
}
}
return true;
}
}
5.划分技能点相等的团队(排序或哈希表)
解题思路
:::warning
首先通过排序,去寻找分组,通过数学归纳法可以知道,当去1的时候不能去找3,因为其他怎么选,任意找两个数可能会比4大,最好的方法是最小的和最大的数去配对。
:::
代码实现(排序)
long sum=0;
int n=skill.length;
long ans=0;
for(int i:skill){
sum+=i;
}
Arrays.sort(skill);
for(int i=0;i<n/2;i++) {
if(skill[i] + skill[n - i - 1]==sum/(n/2)){
ans += skill[i] * skill[n - i - 1];
}else {
return ans=-1;
}
}
return ans;
代码实现(哈希表)
class Solution {
public long dividePlayers(int[] skill) {
long sum = 0;
int len = skill.length;
var map = new HashMap<Long,Integer>();
//求和获取平均值顺便判断一下
for(int item:skill){
sum+=item;
}
if(sum%(len/2)!=0){
return -1;
}
long ave = sum/(len/2);
long ans = 0;
long count = 0;
for(long item:skill){
//判断每个数字var的对立数即ave-var是否已经存在
//存在即可以统计乘积以及并且在表里-1,同时统计参与计算的数字
//不存在则将当前值var存入
int temp = map.getOrDefault(ave-item,0);
if(temp == 0){
map.put( item,map.getOrDefault(item,0)+1);
}else{
count+=2;
ans+=(ave-item)*item;
map.put(ave-item,temp-1);
}
}
//判断参与计算的数字是否刚好为数组长度,否则返回-1
return count == len? ans:-1;
}
}
12.11(力扣周赛)
12.13(接雨水专题)
8. 盛最多水的容器(双指针)
解题思路
首先定义一个双指针,分别指向最左端和最右端,能接的最多的水应该是嘴边的那个边的长度乘以两个柱子的距离,因此只需要找到两组里边一条边是所有边里第二高的即可。
代码实现
class Solution {
public int maxArea(int[] height) {
int left=0;
int right=height.length-1;
int ans=0;
while(left<right){
//int aera=Math.min(height[left],height[right])*(right-left);
//ans=Math.max(ans,area);
ans=Math.max(ans,Math.min(height[left],height[right])*(right-left));
if(height[left]<height[right]){
left++;
}else{
right--;
}
}
return ans;
}
}
9.接雨水(动态规划)
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
假设每一个横坐标都对应一个木桶,这个木桶的所能装的最大的水的面积是左右两边的最小值*宽度,因此需要先记录一下这个格子的左边的最小值和右边的最小值。动态规划的思想。把每一个坐标当成一个木桶,这样我们就可以纪录出来他能装多少水,并且减去他的被占用的体积就可以。
class Solution {
public int trap(int[] height) {
int n=height.length;
int[] left_min=new int[n];
left_min[0]=height[0];
int[] right_min=new int[n];
right_min[n-1]=height[n-1];
for(int i=1;i<n;i++){
left_min[i]=Math.max(left_min[i-1],height[i]);
}
for(int j=n-2;j>=0;j--){
right_min[j]=Math.max(right_min[j+1],height[j]);
}
int ans=0;
for(int i=0;i<n;i++){
ans+=Math.min(left_min[i],right_min[i])-height[i];
}
return ans;
}
}
10.单值二叉树(递归遍历)
思路分析
首先最想先想到的就是遍历所有的数组,因为想统计是否都相同,因此我们可以使用Set集合来收集结果,采用先序遍历即可。
代码实现(线序遍历)
class Solution {
public boolean isUnivalTree(TreeNode root) {
Set set=new HashSet();
isUnivalTree1(root,set);
return set.size()==1;
}
public void isUnivalTree1(TreeNode root,Set set){
set.add(root.val);
if(root.left!=null){
isUnivalTree1(root.left,set);
}
if(root.right!=null){
isUnivalTree1(root.right,set);
}
}
}
12.17(计挑赛模拟)
11. 立方值的平方根为整数 (库函数的应用)
解题思路
使用Java的sqrt并把它转换为int形并接受,取整之后的数字再去减开方的数。
代码实现
public class Main3 {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int N=sc.nextInt();
int ans=1;
for(double i=4;i<N;i++){
double a=0;
a=Math.sqrt(i);
int b = (int) a;
if(a-b==0){
ans++;
}
}
System.out.println(ans);
}
}
12.18(蓝桥杯真题&力扣周赛&Acwing)
12.山(回文数 字符串处理)
解题思路
在这里可以采用直接遍历的手段,首先想到两个条件,一个是数字递增,一个是回文数。
因此只需要判断一个回文数是否满足递增即可。
代码实现
:::success
使用StringBuffer的reverse()方法判断是否翻转后相等。
:::
public class mountian {
public static void main(String[] args) {
long ans=0;
for(long i=2022;i<=2022222022;i++) {
if(check(i)) {
ans++;
}
}
System.out.println(ans);
}
private static boolean check(long i){
String s = String.valueOf(i);
StringBuilder sBuilder = new StringBuilder(s);
if(sBuilder.toString().equals(sBuilder.reverse().toString())){
for(int j=0;j<sBuilder.length()/2;j++){
int pre=Integer.valueOf(sBuilder.charAt(j));
int aft=Integer.valueOf(sBuilder.charAt(j+1));
if(pre>aft) return false;
}
//System.out.println(i);
return true;
}
return false;
}
}
13.统计相似字符串对的数目(集合)
解题思路
:::success
暴力枚举出所有两个分组的字符串数组,将每个字符都存入一个集合中,判断两个集合是否相等。
:::
代码实现(判断集合是否相等)
:::success
如果两个集合的长度相等,并且集合A包含集合B所有即可。
:::
class Solution {
public int similarPairs(String[] words) {
int ans=0;
for (int i = 0; i < words.length; i++) {
for (int j =i+1; j < words.length; j++) {
HashSet set1 = new HashSet<>();
HashSet set2 = new HashSet<>();
for(int l=0; l < words[i].length(); l++){
set1.add(words[i].charAt(l));
}
for(int m=0; m < words[j].length(); m++){
set2.add(words[j].charAt(m));
}
if(set1.size()==set2.size()&&set1.containsAll(set2)){
ans++;
}
}
}
return ans;
}
}
14.统计一个数组中好对子的数目(哈希表getOrDefault)
解题思路
:::success
首先不能暴力枚举,时间复杂度为O(n²),会超时。因此需要减小时间复杂度,可以采用一个方法使用哈希表,使用哈希表的getOrDefault()方法,判断这个数字是否在哈希表中被存放,如果没有存放就返回默认值,
当所有的数字都被遍历完之后统计结果。
nums[i] + rev(nums[j]) == nums[j] + rev(nums[i]) 等价于
nums[i]-rev(nums[i]) 与其他的值相等。
:::
代码实现
:::warning
map.getOrDefault();
返回 key 相映射的的 value,如果给定的 key 在映射关系中找不到,则返回指定的默认值
:::
:::success
统计每一个数字是否有多个,如果存在多个结果+1
:::
class Solution {
private int E=(int) 1e9+7;
public int countNicePairs(int[] a) {
int ans=0;
HashMap<Integer,Integer> map=new HashMap();
for(int n:a){
int sub=n - this.rev(n);
int pairs=map.getOrDefault(sub,0);
ans=(ans+pairs+E)%E;
map.put(sub,pairs+1);
}
return ans;
}
public int rev(int m){
String s=String.valueOf(m);
StringBuilder sb=new StringBuilder(s);
sb=sb.reverse();
String s1 = sb.toString();
return Integer.parseInt(s1);
}
}