LeetCode刷题记录+题解汇总Java实现(一)

991坏了的计算器
在显示着数字的坏计算器上,我们可以执行以下两种操作:
双倍(Double):将显示屏上的数字乘 2;
递减(Decrement):将显示屏上的数字减 1 。
最初,计算器显示数字 X。
返回显示数字 Y 所需的最小操作数。

逆向思维,Y->X

 1. Y为偶数则直接除2,且操作数++
 2. Y为奇数则(Y+1/2,且操作数+=2
 3. 循环至Y<X ,操作数+(X-Y)
 class Solution {
    public int brokenCalc(int x, int y) {
        int result  = 0;
        while(y>x){
            if((y&1)==1){
                y=(y+1)/2;
                result+=2;
            }
            else {
                y/=2;
                result++;
            }
        }
        return result+x-y;
    }
}

890查找和替换模式
输入:words = [“abc”,“deq”,“mee”,“aqq”,“dkd”,“ccc”], pattern = “abb”
输出:[“mee”,“aqq”]
解释:
“mee” 与模式匹配,因为存在排列 {a -> m, b -> e, …}。
“ccc” 与模式不匹配,因为 {a -> c, b -> c, …} 不是排列。
因为 a 和 b 映射到同一个字母。

将pattern借助hashmap数字化,然后对words进行遍历,同样对word进行数字化,若符合word与pattern则为字符串匹配成功
class Solution {
    int [] arrb = null;
    int lb;
   public boolean isok(String a){
        int la = a.length();
        if(la!=lb){
            return false;
        }
        int [] arra = new int[la];
        int k = 0;
        HashMap<Character,Integer> mapa = new HashMap<Character, Integer>();
        for(int i = 0;i<arra.length;i++){
            Character c = a.charAt(i);
            if(mapa.containsKey(c)==false){
                k++;
                mapa.put(c,k);
                arra[i] = k;
            }
            else arra[i] = mapa.get(c);
        }
        return Arrays.equals(arra,arrb);


    }
    public List<String> findAndReplacePattern(String[] words, String pattern) {
            List<String> res = new ArrayList<String>();
            lb = pattern.length();
            arrb = new int[lb];
            int k = 0;
        HashMap<Character,Integer> mapb = new HashMap<Character, Integer>();
            for(int i = 0;i<arrb.length;i++){
                Character c = pattern.charAt(i);
                if(mapb.containsKey(c)==false){
                    k++;
                    arrb[i] = k;
                    mapb.put(c,k);
                }
                else arrb[i] = mapb.get(c);

            }
            mapb.clear();
        for (String word:words
             ) {
            if(isok(word)==true){
                res.add(word);
            }
        }


            return res;
    }
}

567字符串的排列
给定两个字符串 s1 和 s2,写一个函数来判断 s2 是否包含 s1 的排列。
换句话说,第一个字符串的排列之一是第二个字符串的子串。
输入: s1 = “ab” s2 = “eidbaooo”
输出: True
解释: s2 包含 s1 的排列之一 (“ba”).
输入: s1= “ab” s2 = “eidboaoo”
输出: False

数组保存字母出现个数+滑动窗口
注意一些小细节
class Solution {
   int[] arra = new int[26];
     int[] arrb = new int[26];
     public  boolean checkInclusion(String s1, String s2) {
        int l1 = s1.length();
        int l2 = s2.length();
        if(l1==0||l2==0||l1>l2){
            return false;
        }
        for(int i = 0;i<l1;i++)
        {
            arra[s1.charAt(i)-'a']++;
            arrb[s2.charAt(i)-'a']++;
        }
        for(int i = l1;i<=l2;i++){
            if(isok())
                return  true;
            arrb[s2.charAt(i-l1)-'a']--;
            arrb[s2.charAt(i%l2)-'a']++;
        }

    return false;
    }
    public  boolean isok() {
        for (int i = 0; i < 26; i++) {
            if (arra[i] != arrb[i])
                return false;
        }
        return true;
    }
}

001两数之和
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]

#在目标数组内寻找两数和==target
#思路:HashMap存之前数字出现的位置,然后用k2=target-当前数字 去map里找
#注意两数相等的小细节就OK
class Solution {
 public int[] twoSum(int[] nums, int target) {
        HashMap<Integer,Integer> map = new HashMap<Integer, Integer>();
        int ans[] = new int[2];
        for(int i = 0;i<nums.length;i++){
            int k1 =target-nums[i];
            int k2 =nums[i] ;
            if(map.containsKey(k1)==true){
              ans[0] = i;
              ans[1] = map.get(k1);
              return ans;
            }
             map.put(k2,i);
        }
        return ans;
    }


}

002两数相加
给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807

#按题意模拟一遍即可,注意一下进位的处理
#ps:可以用递归去做,效率很高
#非递归:

class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
         List<Integer> la = new ArrayList<Integer>();
        List<Integer> lb = new ArrayList<Integer>();
        List<Integer> lc = new ArrayList<Integer>();
        while(true){
            la.add(l1.val);
            l1 = l1.next;
            if(l1==null){
                break;
            }
        }
        while(true){
            lb.add(l2.val);
            l2 = l2.next;
            if(l2==null){
                break;
            }
        }
        int lmax = Math.max(la.size(),lb.size());
        if(la.size()<lmax){
            for(int i = la.size();i<lmax;i++)
            {
                la.add(0);
            }
        }
        if(lb.size()<lmax){
            for(int i = lb.size();i<lmax;i++){
                lb.add(0);
            }
        }
        int s=0;
        for(int i = 0;i<lmax;i++){

            int v1 = la.get(i);
            int v2 = lb.get(i);
            int v3 = v1+v2+s;
            if(v3>=10){
                s = 1;
                v3-=10;
            }
            else {
                s = 0;
            }
            lc.add(v3);
        }
        if(s!=0)
        {
            lc.add(1);
        }
        ListNode ans = new ListNode(lc.get(0));
        ListNode t ;
        t = ans;
        for(int i = 1;i<lc.size();i++){
            if(t.next==null){
                t.next = new ListNode(lc.get(i));
                t = t.next;
            }
        }

        return ans;
    }
}

你可能感兴趣的:(leetcode)