力扣----算法(一)

目录

1.给定target,找出数组里和为target的数组下标

2.回文数

方法一:暴力法

方法二:


1.给定target,找出数组里和为target的数组下标

题目描述:

 平台提交代码:

测试结果:

思路:

用HashMap表
num数组里面的元素当作Key,方便到时候查找HasjMap里面是否含有这个Key(元素)。
下标当作Value,到时候可以用对应的元素(Key)去查找到下标(Value)
定义一个数组用来存放那两个和为target的元素的下标值
1.从num[0]开始
2.存储:把num[0]存入HashMap,Key是元素,Value是下标


3.查找:计算target-num[1]的值,看看这个值在HashMap里是否存在,用containskey方法  4.存储:存储num[1]
5.如果有,那么把num[1]以及target-num[1]对应的数组元素对应的下标存入自己定义的容量为2的数组,
可以用get方法,通过对应的Key去得到对应的Value(下标)

6.查找:计算targer-num[2]的值,用containskey方法去查找是否存在这个值,
7.存储:如果不包含,那么就继续保存下一个(num[2])到HashMap
8如果有,那么把num[1]以及target-num[1]对应的数组元素对应的下标存入自己定义的容量为2的数组,
可以用get方法,通过对应的Key去得到对应的Value(下标)


9.如果不包含,那么就继续保存下一个(num[2])到HashMap
总之,num[0]只用存储,数组里的数除了num[0]以外的数,进行存储后就计算target-这个数的操作,去在哈希表里面进行查找、
是否存在target-这个数
没有的话就一直进行存储和查找,直到查找到可以和自己加起来的值为target为止 

具体代码: 

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class solution {
    public int[] twoSum(int[]nums, int target){

        int []ret=new int[2];//用来存放下标的数组
        int len=nums.length;
        Map<Integer,Integer> hashmap=new HashMap<>();//用来存放整数数组里面的元素及其下标,元素为Key,下标为Value
        hashmap.put(nums[0],0);//先把num[0]存进哈希表
        for(int i=1;i<len;i++){
            //从下标为1的数组元素开始进行存储再查找的操作
            //一.查找
            //1.算出target-num[i]的值
            int differ=target-nums[i];
            //2.查找哈希表中是否存在这个值,我们把数组里的元素当作了key可用contanisKey的方法查找
            if(hashmap.containsKey(differ)){
                ret[0]=hashmap.get(differ);//用key值获取下标
                ret[1]=i;
            }
            //二.存储
            hashmap.put(nums[i],i);

        }
        return ret;
    }
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        //输入数组
        String str=sc.nextLine().toString();//输入数组的内容,可以读取一整行,包括空格
        str=str.replaceFirst("\\[","");
        str=str.replaceFirst("\\]","");
        String arr[]=str.split(",");//拆分字符串成字符串数组
        int []aw=new int [arr.length];//定义一个长度和arr数组相同的int型的数组
        for(int i=0;i<aw.length;i++){
            aw[i]=Integer.parseInt(arr[i]);//将arr的内容复制到aw中
        }
        //输入target
        int target=sc.nextInt();
        //创建对象调用方法
        solution s1=new solution();
        System.out.println(s1.twoSum(aw,target));
    }

}

注意:

  1. 在运行的时候,如果数组是[3,3]这类具有重复元素的数组,那么我们输出的下标应该是先出现的下标和后出现的下标进行输出,([0,1])而不是输出两个一模一样的下标 ([1,1]),所以在这里应该注意要先进行查找再进行存储。因为当数组里面有相同元素存在时,元素作为Key,那么在第二次进行存储的时候,后面的value会覆盖掉前面的value。
  2. String字符串可以调用replace方法删除字符

去掉 [ 这个符号时,记得加上转义字符\\ 

2.回文数

题目描述:

方法一:暴力法

呜呜呜呜,暴力法太难了,即麻烦,而且时间和空间复杂度都会很大


public class huiwen {
    public boolean isPalindrome(int x) {
        if(x<0)
            return false;
        boolean bool=true;
        String str=String.valueOf(x);//将int型的x转换成了String类型
        int length=str.length();
        char[] num1=new char[length];//创建一个char类型的数组用来存储字符串正序的各位数字
        char[] num2=new char[length];//创建一个数组用来存储字符串逆序的各位数字
        for(int i=0;i<length;i++){
            num1[i]=str.charAt(i);
        }//存储正序数字
        for(int i=length;i>0;i--){
            System.out.println(num2[length-i]=str.charAt(i-1));//从0到length-1
        }//存储逆序数字
        for(int i=0;i<length;i++){
            if(num1[i]!=num2[i]) {
                bool = false;
                break;
            }
        }//比较两个字符数组的元素是否一样,若出现了一个不一样,那么就令bool为FALSE,并跳出循环
       return bool;

    }
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int num=sc.nextInt();
         huiwen h=new huiwen();
         System.out.println(h.isPalindrome(num));
    }
}

思路: 

  1. 如果是负数那么必定不是回文数,返回false,如果是正数那么继续进行判断
  2. 首先把int数据转为String类型的数据
  3. 创建两个char类型的数组,char1和char2分别用来存储转换为String后的字符串的正序和逆序的字符         (用charAt()方法来获取String里面的单个字符)
  4. 然后用for循环来对两个char类型的数组进行比较,如果出现不同的,那么就令boolean bool的值为false,并跳出循环
  5. 返回定义的boolean类型数据

测试结果

方法二:

思路:

1.考虑特殊情况:

负数不可能是回文数,正数的个位数为0的数也不可能为回文数,一个数的开头不可能为0。所以负数以及个位数为0的正数在方法里面返回false

2.我们一般会采取将数字反转过来,再比较两个数是否相等,但是这里会存在数据溢出的风险,当一个数为2472748282919时没有溢出,但是反转过来时数据发生了溢出,这样不可行。我们可以观察到回文数都是对称的数字(奇数位数的数字关于中间的那个数字对称,偶数位数的数字关于中间的一条虚线对称),这时候,我们可以选择只取数字的前一半和后一半,然后把后一半数字反转过来与前一半数字进行比较。

3.在这里我们分两种情况对int x进行取半操作(reverted表示后半部分的数字反转过来)

在正在进行取半操作时,前半部分的数总大于后半部分的数,那什么时候停止呢?

运行到前半部分数等于(这种情况必是偶数位数)或者小于(可以是奇数位数的数字,也可以是偶数位数的数字)后半部分数反转过来的时候停止。

具体看下面分析

后半部分反转过来的数字一点点增大,一开始是小于前半部分的,直到后半部分反转过来的数等于或者大于前半部分,说明,没必要再进行取半这个操作了。

奇数位数的数字:把后半部分反转的数去掉末尾的数字与前半部分比较(因为后半部分的个位数存储了x这个数最中间的数字)

偶数位数的数字:直接后半部分反转过来的数与前半部分比较

具体代码 

class Solution {
    public boolean isPalindrome(int x) {

        if (x < 0 || (x % 10 == 0 && x > 0)) {
            return false;
        }

        int revertedNumber = 0;
        while (x > revertedNumber) {
            revertedNumber = revertedNumber * 10 + x % 10;
            x /= 10;
        }


        return x == revertedNumber || x == revertedNumber / 10;
    }
}

测试结果

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

笃岩_

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

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

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

打赏作者

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

抵扣说明:

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

余额充值