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

leetcode003 无重复字符的最长子串
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/
思路:滑动窗口+HashMap
输入: “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。
1.起始start=0;标志ans从"p"开始
2.map[p] = 0 ,map[w]=1 ,ans = “pw”;
3.当扫描到第2个w的时候,即“pww”不符合题意 ans 为“pw”,但要更新start=2(第1个w的位置+1,即舍去第一个w)
4.map[k]=3,ans=“wk”,map[4]=4,ans=“wke”,
5.当扫描到第3个w的时候,即“wkew”不符合题意,ans为“kew”,但要更新start=3(第2个w的位置+1,即舍去第二个w)
6.注意维护一下最大的ans.length()

class Solution {
  public int lengthOfLongestSubstring(String s) {
        if(s.length()==0){
            return 0;
        }
        HashMap<Character,Integer> map = new HashMap<Character, Integer>();
        int ans = 0;
        int start = 0;
        for(int i = 0 ;i<s.length();i++){
            char temp =s.charAt(i);
            if(map.containsKey(temp)){
                start = Math.max(map.get(temp)+1,start);
            }
                map.put(temp,i);
            ans = Math.max(ans,i-start+1);
        }
        return ans;
    }
}

leetcode004 寻找两个有序数组的中位数
给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。
请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。
你可以假设 nums1 和 nums2 不会同时为空。
https://leetcode-cn.com/problems/median-of-two-sorted-arrays/
nums1 = [1, 2]
nums2 = [3, 4]
则中位数是 (2 + 3)/2 = 2.5
nums1 = [1, 3]
nums2 = [2]
则中位数是 2.0
思路:
可二分实现O(log min(n,m)),本篇只能给出合并数组的解法O(n+m)
注意一下>>1 右移1位 实现 /2
<<1 左移1位 实现*2

class Solution {
 public double findMedianSortedArrays(int[] nums1, int[] nums2) {
            int l1 = nums1.length;
            int l2 = nums2.length;
            int anscnt = l1+l2;
            int nums3[] = new int[anscnt];
            int l3 = 0;
            int i = 0;
            int j = 0;
            while(l3!=anscnt){

                if(i==l1){
                    while (j!=l2){
                        nums3[l3++]=nums2[j++];
                    }
                    break;
                }
                if(j==l2){
                    while(i!=l1){
                        nums3[l3++]=nums1[i++];
                    }
                    break;
                }
                if(nums1[i]>=nums2[j]){
                    nums3[l3++] = nums2[j++];
                }
                else {
                    nums3[l3++] = nums1[i++];
                }
            }
            if((l3&1)==1){
                return nums3[l3>>1];
            }
            else {
                return ((nums3[l3>>1]+nums3[(l3>>1)-1])*1.0)/2;
            }
    }
}

leetcode005 最长回文子串
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
https://leetcode-cn.com/problems/longest-palindromic-substring/
输入: “babad”
输出: “bab”
注意: “aba” 也是一个有效答案。
输入: “cbbd”
输出: “bb”
思路:
1.设s1 为 s的倒置,则s和s1的最长公共子串就是ans
2.以目标串的每个节点为中心,向左右扩散寻找最长的回文子串,

class Solution {
   public int findans(String s,int start,int end){
        while(start>=0&&end<s.length()&&s.charAt(start)==s.charAt(end)){
            start--;
            end++;
        }
        return end-start-1;
    }
    public String longestPalindrome(String s) {
        if(s.length()<1){
            return "";
        }
        int L = 0;
        int R = 0;
        for(int i = 0;i<s.length();i++){
            int l1 = findans(s,i,i);
            int l2 = findans(s,i,i+1);
            int len = Math.max(l1,l2);
            if(len>R-L){
                L = i - (len-1)/2;
                R = i + (len)/2;
            }
        }
        return s.substring(L,R+1);
    }
}

leetcode011 盛最多水的容器
.给定 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
说明:你不能倾斜容器,且 n 的值至少为 2。
https://leetcode-cn.com/problems/container-with-most-water/
LeetCode刷题记录+题解汇总Java实现(二)_第1张图片
图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。
示例:
输入: [1,8,6,2,5,4,8,3,7]
输出: 49
思路:滑动窗口(双指针标记)
由面积的计算=max(ans,底×高)的公式,我们可以去思考如何获得(底×高)的最大值,
即可以从最大的底边开始,l=0,r=height.length-1,则最大底= r-l,对应×min(height[l],height[r])
每次滑动窗口的规则:将小的高往大的高方向靠拢,每次维护ans

class Solution {
    public int maxArea(int[] height) {
        int l = 0;
        int r = height.length-1;

        int ans = 0;
        while(l<r){
            int temp = (r-l)*Math.min(height[l],height[r]);
            if(temp>ans){
                ans = temp;
            }
            if(height[l]<height[r]){
                l++;
            }
            else{
                r--;
            }
        }
        return ans;
    }
}

leetcode017 电话号码的字母组合
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
LeetCode刷题记录+题解汇总Java实现(二)_第2张图片
输入:“23”
输出:[“ad”, “ae”, “af”, “bd”, “be”, “bf”, “cd”, “ce”, “cf”].
思路:初始化定义好数字字符对应的字母映射即telmap
通过队列实现BFS,也可以递归实现

class Solution {
HashMap<Character,char[]> telmap;
    List<String> anslist;
    public  void init(){
        telmap = new HashMap<Character, char[]>();

        telmap.put('2',new char[]{'a','b','c'});
        telmap.put('3',new char[]{'d','e','f'});
        telmap.put('4',new char[]{'g','h','i'});
        telmap.put('5',new char[]{'j','k','l'});
        telmap.put('6',new char[]{'m','n','o'});
        telmap.put('7',new char[]{'p','q', 'r','s'});
        telmap.put('8',new char[]{'t','u','v'});
        telmap.put('9',new char[]{'w','x','y','z'});
    }
    public List<String> letterCombinations(String digits) {
        anslist= new ArrayList<String>();
        if(digits.length()<=0){
            return anslist;
        }
        init();
        Queue<String>q = new LinkedList<String>();
        char d0  = digits.charAt(0);
        for(int i = 0;i<telmap.get(d0).length;i++){
            String temp = new String();
            temp+=telmap.get(d0)[i];
            q.add(temp);
        }
        while(!q.isEmpty()){
            String ct = q.poll();
            if(ct.length()==digits.length()){
                anslist.add(ct);
                continue;
            }
            char[] dt = telmap.get(digits.charAt(ct.length()));
            for(int i = 0;i<dt.length;i++){
                String next = new String();
                next = ct+dt[i];
                q.add(next);
            }
        }
        return anslist;
    }
}

你可能感兴趣的:(leetcode)