力扣----算法(一)

目录

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

2.回文数

方法一:暴力法

方法二:


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

题目描述:

力扣----算法(一)_第1张图片 平台提交代码:力扣----算法(一)_第2张图片

测试结果:力扣----算法(一)_第3张图片

思路:

用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 hashmap=new HashMap<>();//用来存放整数数组里面的元素及其下标,元素为Key,下标为Value
        hashmap.put(nums[0],0);//先把num[0]存进哈希表
        for(int i=1;i

注意:

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

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

2.回文数

题目描述:

力扣----算法(一)_第4张图片

方法一:暴力法

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


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;i0;i--){
            System.out.println(num2[length-i]=str.charAt(i-1));//从0到length-1
        }//存储逆序数字
        for(int i=0;i

思路: 

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

测试结果

力扣----算法(一)_第5张图片

方法二:

思路:

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;
    }
}

测试结果

力扣----算法(一)_第6张图片

你可能感兴趣的:(算法)