Java习题1

1.输入1~100数据,存放到创建的集合中,集合的元素和达到200时停止输入

import java.util.ArrayList;
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        ArrayList<Integer>list=new ArrayList<>();
        Scanner sc =new Scanner(System.in);
        while(true){
            System.out.println("请输入一个整数");
            String number=sc.next();
            int num=Integer.parseInt(number);
            if(num<1||num>100){
                System.out.println("数据错误");
                continue;
            }
            list.add(num);
            int sum=getSum(list);
            if(sum>200)
                break;
        }
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
    }
    private static int getSum(ArrayList<Integer> list) {
        int sum=0;
        for (int i = 0; i < list.size(); i++) {
            int num=list.get(i);
            sum+=num;
        }
        return sum;
    }
}

对角线上不同值的数量差

给你一个下标从 0 开始、大小为 m x n 的二维矩阵 grid ,请你求解大小同样为 m x n 的答案矩阵 answer 。

矩阵 answer 中每个单元格 (r, c) 的值可以按下述方式进行计算:

令 topLeft[r][c] 为矩阵 grid 中单元格 (r, c) 左上角对角线上 不同值 的数量。
令 bottomRight[r][c] 为矩阵 grid 中单元格 (r, c) 右下角对角线上 不同值 的数量。
然后 answer[r][c] = |topLeft[r][c] - bottomRight[r][c]| 。

返回矩阵 answer 。

矩阵对角线 是从最顶行或最左列的某个单元格开始,向右下方向走到矩阵末尾的对角线。

如果单元格 (r1, c1) 和单元格 (r, c) 属于同一条对角线且 r1 < r ,则单元格 (r1, c1) 属于单元格 (r, c) 的左上对角线。类似地,可以定义右下对角线。

示例 1:


输入:grid = [[1,2,3],[3,1,5],[3,2,1]]
输出:[[1,1,0],[1,0,1],[0,1,1]]
解释:第 1 个图表示最初的矩阵 grid 。 
第 2 个图表示对单元格 (0,0) 计算,其中蓝色单元格是位于右下对角线的单元格。
第 3 个图表示对单元格 (1,2) 计算,其中红色单元格是位于左上对角线的单元格。
第 4 个图表示对单元格 (1,1) 计算,其中蓝色单元格是位于右下对角线的单元格,红色单元格是位于左上对角线的单元格。
- 单元格 (0,0) 的右下对角线包含 [1,1] ,而左上对角线包含 [] 。对应答案是 |1 - 0| = 1 。
- 单元格 (1,2) 的右下对角线包含 [] ,而左上对角线包含 [2] 。对应答案是 |0 - 1| = 1 。
- 单元格 (1,1) 的右下对角线包含 [1] ,而左上对角线包含 [1] 。对应答案是 |1 - 1| = 0 。
其他单元格的对应答案也可以按照这样的流程进行计算。
示例 2:

输入:grid = [[1]]
输出:[[0]]
解释:- 单元格 (0,0) 的右下对角线包含 [] ,左上对角线包含 [] 。对应答案是 |0 - 0| = 0 。
 

提示:

m == grid.length
n == grid[i].length
1 <= m, n, grid[i][j] <= 50

传送门

分析

题目的意思是:取某个点的左上部分的有多少个不重复数字,右上部分有多少个不重复数字,然后取他们差值的绝对值作为新数组的值

因为是存放不重复的元素,我们使用HashSet来实现添加不重复元素的这个操作会更为方便

import java.util.*;

import java.util.*;

public class Main {
    static int grid[][];
    static int n, m;

    public static void main(String[] args) {
        grid = new int[][]{{1, 2, 3}, {3, 1, 5}, {3, 2, 1}};
        int ans[][] = differenceOfDistinctValues(grid);
        for (int i = 0; i < ans.length; i++) {
            for (int i1 = 0; i1 < ans[i].length; i1++) {
                System.out.print(ans[i][i1] + " ");
            }
            System.out.println(" ");
        }
    }

    public static int abc(int[][] grid, int x, int y, boolean flat) {
        Set<Integer> ha = new HashSet<>();
        if (flat) {
            while (x > 0 && y >0) {
                ha.add(grid[--x][--y]);
            }
        } else {
            while (x < n-1 && y < m-1) {
                ha.add(grid[++x][++y]);
            }
        }
        return ha.size();
    }

    public static int[][] differenceOfDistinctValues(int grid[][]) {
        n = grid.length;
        m = grid[0].length;
        int ans[][] = new int[n][m];
        for (int i = 0; i < n; i++) {
            for (int i1 = 0; i1 < m; i1++) {
                ans[i][i1] = Math.abs(abc(grid, i, i1, true) - abc(grid, i, i1, false));
            }
        }
        return ans;
    }
}

使所有字符相等的最小成本

给你一个下标从 0 开始、长度为 n 的二进制字符串 s ,你可以对其执行两种操作:

选中一个下标 i 并且反转从下标 0 到下标 i(包括下标 0 和下标 i )的所有字符,成本为 i + 1 。
选中一个下标 i 并且反转从下标 i 到下标 n - 1(包括下标 i 和下标 n - 1 )的所有字符,成本为 n - i 。
返回使字符串内所有字符 相等 需要的 最小成本 。

反转 字符意味着:如果原来的值是 '0' ,则反转后值变为 '1' ,反之亦然。

示例 1:

输入:s = "0011"
输出:2
解释:执行第二种操作,选中下标 i = 2 ,可以得到 s = "0000" ,成本为 2 。可以证明 2 是使所有字符相等的最小成本。
示例 2:

输入:s = "010101"
输出:9
解释:执行第一种操作,选中下标 i = 2 ,可以得到 s = "101101" ,成本为 3 。
执行第一种操作,选中下标 i = 1 ,可以得到 s = "011101" ,成本为 2 。
执行第一种操作,选中下标 i = 0 ,可以得到 s = "111101" ,成本为 1 。
执行第二种操作,选中下标 i = 4 ,可以得到 s = "111110" ,成本为 2 。
执行第一种操作,选中下标 i = 5 ,可以得到 s = "111111" ,成本为 1 。
使所有字符相等的总成本等于 9 。可以证明 9 是使所有字符相等的最小成本。 
 

提示:

1 <= s.length == n <= 105
s[i] 为 '0' 或 '1'

分析

直接从中间分为两段,第一段中前与后数组不相同就进行相加,第二段从后面开始遍历,前与后不相同就进行相加

public class Main {
    static String s="010101";
    public static void main(String[] args) {
        int ans=mininumCost();
        System.out.println(ans);
    }
    public static int mininumCost(){
        int ans=0;
        char arr[]=s.toCharArray();
        int len=s.length(),n=len/2;
        for(int i=0;i<n;i++){
            if(arr[i]!=arr[i+1]){
                ans+=i+1;
            }
        }
        for(int i=len-1;i>n;i--){
            if(arr[i]!=arr[i-1]){
                ans+=len-i;
            }
        }
        return ans;
    }
}

长度最小的子数组

给定一个含有 n 个正整数的数组和一个正整数 target 。

找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

示例 1:

输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
示例 2:

输入:target = 4, nums = [1,4,4]
输出:1
示例 3:

输入:target = 11, nums = [1,1,1,1,1,1,1,1]
输出:0
 

提示:

1 <= target <= 109
1 <= nums.length <= 105
1 <= nums[i] <= 105
分析:

如果当前子段和大于target,就需要减少所需数组中的元素个数,就采用left++的方式了来缩短数组中的元素个数并更新最小所需的元素个数。

如果当前字段和小于target,就需要增加所需数组中的元素个数,就right++的方式来增加数组中的元素个数,

public class Main {
    static int nums[]={2,3,1,2,4,3};
    static int target=7;
    public static void main(String[] args) {
        int ans= minSubArrayLen();
        System.out.println(ans);
    }
    private static int minSubArrayLen(){
        int len=nums.length;
        int left=0;
        int s=0,ans=999999;
        for (int right = 0; right < len; right++) {
            s+=nums[right];
            while(s>=target){
                ans=Math.min(ans,(right-left+1));
                s-=nums[left++];
            }
        }
        if(ans==999999)
        return 0;
        else
            return ans;
    }
}

6465. 执行子串操作后的字典序最小字符串

难度中等

给你一个仅由小写英文字母组成的字符串 s 。在一步操作中,你可以完成以下行为:

  • 选则 s 的任一非空子字符串,可能是整个字符串,接着将字符串中的每一个字符替换为英文字母表中的前一个字符。例如,'b' 用 'a' 替换,'a' 用 'z' 替换。

返回执行上述操作 恰好一次 后可以获得的 字典序最小 的字符串。

子字符串 是字符串中的一个连续字符序列。

现有长度相同的两个字符串 x 和 字符串 y ,在满足 x[i] != y[i] 的第一个位置 i 上,如果  x[i] 在字母表中先于 y[i] 出现,则认为字符串 x 比字符串 y 字典序更小 。

示例 1:

输入:s = "cbabc"
输出:"baabc"
解释:我们选择从下标 0 开始、到下标 1 结束的子字符串执行操作。 
可以证明最终得到的字符串是字典序最小的。

示例 2:

输入:s = "acbbc"
输出:"abaab"
解释:我们选择从下标 1 开始、到下标 4 结束的子字符串执行操作。
可以证明最终得到的字符串是字典序最小的。

示例 3:

输入:s = "leetcode"
输出:"kddsbncd"
解释:我们选择整个字符串执行操作。
可以证明最终得到的字符串是字典序最小的。

提示:

  • 1 <= s.length <= 3 * 105
  • s 仅由小写英文字母组成

分析:题目意思为需要我们将源字符串进行变形,如果符合题目要求就将其ASCII码值进行-1

但是我们需要考虑,什么时候进行-1

我们需要从头开始遍历,如果没遇到'a',就进行-1,遇到'a'后就停止遍历,可以直接return ,因为后面的字符串不需要我们进行变化了,也就是说,我们一直进行-1知道遇到了第一个'a'

如果我们第一个就遇到了'a',我们还需要对后面的字符串进行变化,知道遍历到最后一个字符或是遇到第二个'a',如需要将"aba"变为"aaa"

要是全为字符'a',就需要将最后一个字符a变为'z'


public class One{
    static String s="aba";
    public static void main(String[] args) {
        String ans=smallsetString();
        System.out.println(ans);
    }
    public static String smallsetString(){
        var ans=s.toCharArray();
        String ss="";
        for (int i = 0; i < s.length(); i++) {
            if(ans[i]>'a'){
                for(;i<s.length()&&ans[i]>'a';i++){
                    ans[i]--;
                }
                return ss=String.valueOf(ans);
            }
        }
        ans[s.length()-1]='z';
        return ss=String.valueOf(ans);
    }
}

15. 三数之和

难度中等

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != ji != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请

你返回所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。

示例 1:

输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。
注意,输出的顺序和三元组的顺序并不重要。

示例 2:

输入:nums = [0,1,1]
输出:[]
解释:唯一可能的三元组和不为 0 。

示例 3:

输入:nums = [0,0,0]
输出:[[0,0,0]]
解释:唯一可能的三元组和为 0 。

提示:

  • 3 <= nums.length <= 3000
  • -105 <= nums[i] <= 105
import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class One {
    static int []nums={1,-1,-1,0};
    public static void main(String[] args) {
        List<List<Integer>>ans=threeSum();
        System.out.println(ans);
    }
    public static List<List<Integer>> threeSum(){
        List<List<Integer>> result = new ArrayList<>();
        Arrays.sort(nums);
        for(int i = 0 ; i < nums.length-2 ; i++){
            if(i>0 && nums[i] == nums[i-1] ){
                continue;
            }
            int left = i + 1;
            int right = nums.length - 1;

            while(left < right){
                int sum = nums[i] + nums[left] + nums[right];
                if(sum > 0){
                    right --;
                }else if (sum < 0){
                    left ++;
                }else{
                    result.add(Arrays.asList(nums[i],nums[left],nums[right]));
                    while(left<right&&nums[left]==nums[left+1])
                        left++;
                    while(left<right&&nums[right]==nums[right-1])
                        right--;
                    
                        left++;
                     right--;
                }
            }
        }
        return result;
    }
}

分析:这个题可以和上面的两数之和思路一样

对数组进行排序后,我们从数组从0到n-2中选取一个数坐标i作为基准x,取i+1作为left,取n-1作为right,然后在while(left<right)循环中,如果x+nums[right]+nums[left]==0,说明满足题目条件,并且我们需要排重

注意1:为什么是从0到n-3?

因为n-2和n-1要作为left和right

注意:为什么需要排重?

因为题目所说不包含重复的三元组

还可以继续两个小优化

因为我们取的num[i]是小于0的,如果是大于0的我们就可以直接brreak;

 if(nums[i]>0)
     break;

如果前面三个小的数相加>0,那么也可以直接break

if(nums[i]+nums[i+1]+nums[i+2]>0)
   break;

6461. 判断一个数是否迷人

难度简单

给你一个三位数整数 n 。

如果经过以下修改得到的数字 恰好 包含数字 1 到 9 各一次且不包含任何 0 ,那么我们称数字 n 是 迷人的 :

  • 将 n 与数字 2 * n 和 3 * n 连接 。

如果 n 是迷人的,返回 true,否则返回 false 。

连接 两个数字表示把它们首尾相接连在一起。比方说 121 和 371 连接得到 121371 。

示例 1:

输入:n = 192
输出:true
解释:我们将数字 n = 192 ,2 * n = 384 和 3 * n = 576 连接,得到 192384576 。这个数字包含 1 到 9 恰好各一次。

示例 2:

输入:n = 100
输出:false
解释:我们将数字 n = 100 ,2 * n = 200 和 3 * n = 300 连接,得到 100200300 。这个数字不符合上述条件。

提示:

  • 100 <= n <= 999

分析:这个题主要是用HashSet的查重就很快就了

class Solution {
    public boolean isFascinating(int n) {
       String s=String.valueOf(n)+String.valueOf(n*2)+String.valueOf(n*3);
        char arr[]=s.toCharArray();
        var book=new HashSet();
        for (int i = 0; i < arr.length; i++) {
            if(arr[i]=='0')
                return false;
            boolean judge=book.add(arr[i]);
            if(judge==false)
                return false;
        }
        return true;
    }
}

本周的做题情况

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值