【JAVA每日刷题】

蓝桥云课:
🔣1.最长子序列
题目:
我们称一个字符串 S 包含字符串 T 是指 T是 S的一个子序列,即可以从字符串 S中抽出若干个字符,它们按原来的顺序组合成一个新的字符串与 T完全一样。
给定两个字符串 S和 T,请问 T中从第一个字符开始最长连续多少个字符 被 S包含?

示例

输入

ABCDEABCD 
AABZ

输出
3
思路:
双指针:一个对着S,一个对着T,从起始位置开始判断,如果相等,t指针往下走,最后s指针走
code:

import java.util.Scanner;

public class 最长子序列 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        char[] s = sc.next().toCharArray();
        char[] t = sc.next().toCharArray();
        //双指针  i对着s   j对着t
        int i = 0;
        int j = 0;
        while (i < s.length && j < t.length){
            if(s[i]==t[j]){
                j++;
            }
            i++;
        }
        System.out.println(j);
    }
}

🔣2.数位排序
题目:
小蓝对一个数的数位之和很感兴趣, 今天他要按照数位之和给数排序。当 两个数各个数位之和不同时, 将数位和较小的排在前面, 当数位之和相等时, 将数值小的排在前面。
例如, 2022 排在 409 前面, 因为 2022 的数位之和是 6, 小于 409 的数位 之和 13 。
又如, 6 排在 2022 前面, 因为它们的数位之和相同, 而 6 小于 2022 。
给定正整数 n, m 请问对 1 到 n采用这种方法排序时, 排在第 m个的元 素是多少?
思路:
对数位和进行分组,也就是数位和为1是一组,并将其里面元素排序,数位和为2的元素为一组,并将其里面的数据排序以此类推。因为形成一对多的情况,采用哈希表(Map映射)。
code:

import java.util.*;

public class 数位排序 {

    //Key  Integer    Value  集合
    static Map<Integer, List<Integer>> map = new HashMap<>();

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();

        //进行分组,数位和是1.存的都是1
        for (int i = 1; i <= n; i++) {
            add(check(i), i);
        }

        //获得  Key   的集合
        List<Integer> list = new ArrayList<>(map.keySet());

        //排序
        Collections.sort(list);
        for (Integer integer : list) {

            //获取当前集合里面的数位和
            List<Integer> q = map.get(integer);
            if (m > q.size()) {
                m -= q.size();
                continue;
            }
            Collections.sort(q);
            System.out.println(q.get(m - 1));
            break;
        }

    }

    //封装函数
    //作用 往 第a个list存入b
    public static void add(int a, int b) {
        if (!map.containsKey(a)) {
            map.put(a, new ArrayList<>());
        }
        //把元素b放入到结合a
        map.get(a).add(b);
    }

    //数位和
    public static int check(Integer x) {
        int res = 0;
    while (x != 0) {
        res += x % 10;
        x = x / 10;
    }
    return res;
}

}

🔣3.子串分值和
题目:
对于一个字符串 S,我们定义 S 的分值 f(S) 为 S 中出现的不同的字符个数。例如 f(“aba”) = 2,f(“abc”) = 3, f(“aaa”) = 1f(“aba”)=2,f(“abc”)=3,f(“aaa”)=1。
现在给定一个字符串 S [0…n − 1]S[0…n−1](长度为 nn),请你计算对于所有 SS 的非空子串 S [i…j](0 ≤ i ≤ j < n)Si…j,f(S [i…j])f(S[i…j]) 的和是多少。
思路:
贡献思想,比如前面没有a,a第一次出现贡献最大,一分 例如:…a… 就有4 x 4=16种情况(包括不选)
当前位置 i 减 上次出现的位置(s[i] - ‘a’) 乘以 n-当前位置 i
将字符串转为字符数组,因为字符串只要求大写字母,所以开一个26大小的数组last,先将last全部填充为-1,
code:

import java.util.Arrays;
import java.util.Scanner;

public class 子串分值和 {
    static int[] last = new int[26];

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        char[] s = sc.next().toCharArray();
        long ans = 0;
        int n = s.length;
        Arrays.fill(last, -1);
        for (int i = 0; i < n; i++) {
            ans += (long) (i - last[s[i] - 'a']) * (n - i);
            last[s[i] - 'a'] = i;
        }
        System.out.println(ans);
    }
}

Leetcode:
🔣1.差值
题目:
给你一个整数 n,请你帮忙计算并返回该整数「各位数字之积」与「各位数字之和」的差。

输入:n = 234
输出:15
解释:
各位数之积 = 2 * 3 * 4 = 24
各位数之和 = 2 + 3 + 4 = 9
结果 = 24 - 9 = 15

思路:
分别计算 数位积 和 数位和 做差即可。
code:

import java.util.Scanner;

public class Test1281 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        System.out.println(subtractProductAndSum(n));
    }

    public static int subtractProductAndSum(int n) {
        return ji(n) - check(n);
    }

    public static int check(int x) {
        int ans = 0;
        while (x != 0) {
            ans += x % 10;
            x /= 10;
        }
        return ans;
    }

    public static int ji(int x) {
        int ans = 1;
        while (x != 0) {
            ans *= x % 10;
            x /= 10;
        }
        return ans;
    }
}

🔣2.两数之和
题目:
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 **和为目标值 **target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
思路:
哈希表(Map映射)
A + B = target,A就是nums[i],那么B就是 target - nums[i]。遍历数组,如果存在B,直接返回B,i,两个都是索引,否则,添加到哈希表中。
code:

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public class Test1 {
    public static void main(String[] args) {
        int[] nums = {2, 7, 11, 15};
        System.out.println(Arrays.toString(twosum(nums, 9)));
    }

    public static int[] twosum(int[] nums, int target) {
        Map<Integer,Integer> hashmap=new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            if(hashmap.containsKey(target-nums[i])){
                return new int[]{hashmap.get(target-nums[i]),i};
            }
            hashmap.put(nums[i],i);
        }
        return new int[0];
    }
}

🔣3.寻找旋转排序数组中的最小值
题目:
已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组。例如,原数组 nums = [0,1,2,4,5,6,7] 在变化后可能得到:

  • 若旋转 4 次,则可以得到 [4,5,6,7,0,1,2]
  • 若旋转 7 次,则可以得到 [0,1,2,4,5,6,7]

注意,数组 [a[0], a[1], a[2], …, a[n-1]] 旋转一次 的结果为数组 [a[n-1], a[0], a[1], a[2], …, a[n-2]] 。
给你一个元素值 互不相同 的数组 nums ,它原来是一个升序排列的数组,并按上述情形进行了多次旋转。请你找出并返回数组中的 最小元素
你必须设计一个时间复杂度为 O(log n) 的算法解决此问题。
输入:nums = [3,4,5,1,2]
输出:1
解释:原数组为 [1,2,3,4,5] ,旋转 3 次得到输入数组。
思路:
二分:根据二段性,因为是升序在进行翻转,所以从某个地方分开,两边都是递增的.我判断nums[mid]与nums[right]大小,如果nums[mid]>nums[right],更改左边区间(即不要左边区间),left来到mid+1区间 left=mid+1,否则更改右边区间,right来到mid位置。最后返回nums[left]的值,就是最小值。
code:

class Solution {
    public int findMin(int[] nums) {
        int l=0;
        int r=nums.length-1;
        while(l<r){
            int mid=l+(r-l)/2;
            if(nums[mid]>nums[r]){
                l=mid+1;
            }else r=mid;
        }
        return nums[l];
    }
}

🔣4.寻找峰值
题目:
峰值元素是指其值严格大于左右相邻值的元素。
给你一个整数数组 nums,找到峰值元素并返回其索引。数组可能包含多个峰值,在这种情况下,返回 任何一个峰值 所在位置即可。
你可以假设 nums[-1] = nums[n] = -∞ 。
你必须实现时间复杂度为 O(log n)_ _的算法来解决此问题。
输入:nums = [1,2,3,1]
输出:2
解释:3 是峰值元素,你的函数应该返回其索引 2。
思路:
二分:因为是山峰数组,所以必然整个区间有最大值mid,而且nums[mid]大于nums[mid-1]和nums[mid]>nums[mid+1],所以我们只需要判断nums[mid]如果大于nums[mid+1]的话舍去右边区间,因为右边不会在比mid+1大了已经,此时right来到mid位置 r= mid;否则 left 来到 mid+1的位置
l=left+1;最后返回left。
code:

class Solution {
    public int findPeakElement(int[] nums) {
        if(nums.length==1){
            return 0;
        }
        int l=0;
        int r=nums.length-1;
        while(l<r){
            int mid=l+(r-l)/2;
            if(nums[mid]>nums[mid+1]){
                r=mid;
            }else l=mid+1;
        }
        return l;
    }
}

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凇:)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值