千锤百炼之每日算法(二)

目录

题外话

正题

第一题

第一题思路

第一题代码详解

第二题

第二题思路

第二题代码详解

第三题

第三题思路

第三题代码详解

关于HashSet类型题

第一题

第一题思路

第一题代码详解

第二题

第二题思路

第二题代码详解

第三题

第三题思路

第三题代码详解

小结


 

题外话

本来几天前就想把这一篇内容写出来了,但是算法题还是不太会,算法题属于综合应用了,学的太着急还是不太行

我仍然知道,努力才能谱写出最绚烂的华章

正题

第一题

统计2出现的次数

请统计某个给定范围[L, R]的所有整数中,数字2出现的次数。
比如给定范围[2, 22],数字2在数2中出现了1次,在数12中出现1次
在数20中出现1次,在数21中出现1次,在数22中出现2次,所以数字2在该范围内一共出现了6次。

第一题思路

1.我们要统计l到r之间2出现的次数,我们需要知道每一个数字中2出现的次数

2.我们要不断模10,除10,判断每一个数字的每一位是否等于2即可

第一题代码详解

public  int test8()
{
    //输入l和r
    Scanner s=new Scanner(System.in);
    int l=s.nextInt();
    int r=s.nextInt();
    //创建count以便统计2出现的次数
    int count=0;
    //使用for循环从l到r每个数字进行统计2
   for (int i=l;i<=r;i++)
   {
       //创建临时变量将i赋值
       int tmp=i;
       //当tmp不等于0
       while (tmp!=0)
       {
           //先模10如果等于2则count++
           if (tmp%10==2) {
               count++;
           }
           //tmp等于tmp除以10
               tmp/=10;
          

       }
   }
    return count;
}

第二题

数组公共元素

给定两个整数数组分别为nums1, nums2,找到它们的公共元素并按返回。
数据范围:
1≤nums1.length, nums2.length≤1000
1≤nums1[i], nums2[i] < 1000

第二题思路

1.根据返回值可看出,返回值具有唯一性也具有无序性

2.思考一下,无论是num1还是num2,里面都有可能出现元素重复

3.首先就要想到HashSet存放的元素是不可重复的

4.我们只需要将其中一个数组放入到HashSet中去

 再通过遍历另一个数组,找到公共的值,如果有公共值就放入ArrayList集合中,并且把公共值从HashSet中移除,因为数组中会有元素重复,而且我们只想找到唯一的公共元素

如下图

第二题代码详解

public ArrayList<Integer> test09(ArrayList<Integer> nums1,ArrayList<Integer> nums2) {


    //返回值是ArrayList<Integer>,先new个对象
    ArrayList<Integer> arr=new ArrayList<>();


    //创建一个HashSet对象set1,并调用构造方法把nums1作为对象传参
    //大家可以去看看HashSet的构造方法是可以传Collection的子类的
    HashSet<Integer> set1 = new HashSet<>(nums1)

;
    //foreach循环
    for(int j:nums2)
    {
        //如果set1包含j
        if(set1.contains(j))
        {
            //将j放入arr中
            arr.add(j);
            //并且移除set1中的j,以免后续出现重复问题
            set1.remove(j);
        }
    }
    //返回arr即可
    return arr;

}

第三题

点击消除

牛牛拿到了一个字符串。
他每次“点击”,可以把字符串中相邻两个相同字母消除,例如,字符串"abbc"点击后可以生成"ac"。
但相同而不相邻、不相同的相邻字母都是不可以被消除的。
牛牛想把字符串变得尽可能短。他想知道,当他点击了足够多次之后,字符串的最终形态是什么?

第三题思路

1.这里其实很像括号匹配,只是将括号换成了字母

比如

2.我们可以把输入的字符串放到char数组中

3.将char数组中的元素一个一个放到StringBuffer中并且放元素的时候和StringBuffer中最后一个元素进行比较,如果相等则删除StringBuffer中元素,不相等则将char数组元素添加进StringBuffer中

4.最后判断StringBuffer长度是否为0即可

第三题代码详解

ublic void test10()
{
    Scanner scanner=new Scanner(System.in);
    //将输入的字符串转换为char数组
    char[] ch=scanner.next().toCharArray();
    //创建StringBuffer
    StringBuffer sb=new StringBuffer();
    //将ch数组中第一个元素加入sb中
    sb.append(ch[0]);
    for (int i = 1; i < ch.length; i++) {


        //如果数组长度不为0并且数组元素等于sb最近添加的元素,则把sb最近添加元素删除
        if (sb.length()!=0&&ch[i]==sb.charAt(sb.length()-1))
        {
            sb.deleteCharAt(sb.length()-1);
        }
        //不满足上述条件则将ch[i]放入sb中
        else {
            sb.append(ch[i]);
        }
    }
    //最后判断sb长度是否为0,并输出判断结果
    System.out.println(sb.length() == 0 ? 0 : sb.toString());
}

关于HashSet类型题

这里我再弄几道HashSet相关类型题,大家可以做一做

第一题

只出现一次的数字 

给你一个 非空 整数数组 nums ,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

你必须设计并实现线性时间复杂度的算法来解决此问题,且该算法只使用常量额外空间。

第一题思路

1.首先利用HashSet将元素一个一个放入,并判断是否包含元素,如果包含此元素说明该元素不止出现了一次,将该元素移除

2.最后遍历HashSet将只出现一次的元素返回即可

第一题代码详解

//只出现一次的数字
public int singleNumber(int[] nums) {

//创建HashSet对象
    HashSet<Integer> set=new HashSet<>();

//创建变量x用于储存数组元素
    int x=0;
    for(int i=0;i<nums.length;i++)
    {

//将nums第i个元素赋值x
        x=nums[i];

//如果set中不包含x,则放入set中
        if(!set.contains(x))
        {
            set.add(x);
        }

//如果包含x则移除x
        else{
            set.remove(x);
        }
    }

//最后进行foreach循环
    for(int a:set)
    {

//如果set中包含a则返回a即可
        if(set.contains(a))
        {
            return a;
        }

    }

//如果nums中没有只出现一次的元素则直接返回-1
    return -1;
}

第二题

宝石与石头

给你一个字符串 jewels 代表石头中宝石的类型,另有一个字符串 stones 代表你拥有的石头。 stones 中每个字符代表了一种你拥有的石头的类型,你想知道你拥有的石头中有多少是宝石。

字母区分大小写,因此 "a" 和 "A" 是不同类型的石头。

第二题思路

1.我们将宝石jewels字符串转换成char类型放入HashSet中

2.遍历stones数组并且判断HashSet中是否包含stones元素

3.创建计数变量count=0,如果HashSet中是否包含stones元素则让count++最后返回count

第二题代码详解

public int numJewelsInStones(String jewels, String stones) {
    //创建泛型为Character的HashSet
    HashSet<Character> set=new HashSet<>();
    //创建计数变量count
    int count=0;
    //遍历jewels元素并放入set中
    for(int i=0;i<jewels.length();i++)
    {
        //将jewels元素转换成char类型放入set中
        set.add(jewels.charAt(i));
    }
    //遍历stones元素
    for(int i=0;i<stones.length();i++)
    {
        //将stones转换成字符串并判断set是否包含
        if(set.contains(stones.charAt(i)))
        {
            //如果包含则count++
            count++;
        }
    }
    //最后返回count
    return count;
}

第三题

坏键盘打字 

旧键盘上坏了几个键,于是在敲一段文字的时候,对应的字符就不会出现。现在给出应该输入的一段文字、以及实际被输入的文字,请你列出肯定坏掉的那些键。

输入在2行中分别给出应该输入的文字、以及实际被输入的文字。每段文字是不超过80个字符的串,由字母A-Z(包括大、小写)、数字0-9、
以及下划线“_”(代表空格)组成。题目保证2个字符串均非空。
输出描述按照发现顺序,在一行中输出坏掉的键。其中英文字母只输出大写,每个坏键只输出一次。题目保证至少有1个坏键。

第三题思路

1.根据示例我们可以看出,输入共有两行,第一行是想要输入的值,第二行是因为键盘坏了实际输出的值

2.输出因为键盘坏了没有输出的值,一个值只输出唯一一次,而且输出变成大写形式

3.我们先将第二行也就是因为键盘坏了实际输入的字符串转成大写并且转换成字符形式放入HashSet(set1)中

4.遍历第一行,并且判断set1元素是否包含第一行元素,如果不包含,新建并放入另一个HashSet中(set2),为了确保输出唯一性,我们要判断set1和set2都不包含第一行元素再输出(具体看代码)

第三题代码详解

public void fun()
{
    //输入第一行和第二行元素
    Scanner s=new Scanner(System.in);
    String str1=s.nextLine();
    String str2=s.nextLine();
    //创建两个HashSet对象
    HashSet<Character> set1=new HashSet<>();
    HashSet<Character> set2=new HashSet<>();
    //将str2转换成大写并转换成字符型放入set1中
    for(char ch:str2.toUpperCase().toCharArray())
    {

        set1.add(ch);

    }
    //遍历str1中元素
    for (char ch:str1.toUpperCase().toCharArray())
    {
        //如果set1中不包含并且set2中也不包含str1中元素
        if (!set1.contains(ch)&&!set2.contains(ch))
        {
            //则输出该元素,并添加到set2中
            System.out.println(ch);
            set2.add(ch);
        }
    }
}

小结

最近天气变热了,大家注意防暑哦

麻烦家人们给个三连(点赞关注收藏!!!)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值