01-hot100

1、两数相加 

  用HashMap

2、两个链表对应位相加

  用一个carry变量记录进制

3、无重复字符的最长字串

  用滑动窗口和HashSet

10. 正则表达式匹配

  动态规划

描述:

给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.' 和 '*' 的正则表达式匹配。

'.' 匹配任意单个字符
'*' 匹配零个或多个前面的那一个元素

11. 盛水最多的容器

      双指针

描述:

给你 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0) 。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

 15. 三数之和

   排序+双指针

描述:

给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。

在力扣基础上优化后的代码

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> ans = new ArrayList<List<Integer>>();
        int nLen  = nums.length;

        Arrays.sort(nums);

        for(int first = 0;first<nLen;++first){
            if(first>0 && nums[first] == nums[first-1]){
                continue;
            }
           int second = first+1;
           int third = nLen-1;
           int beforeSecond = -1;
           int target = -nums[first];
           while( second < third ){
               if(nums[second]+nums[third] == target){
                   if(beforeSecond == -1 || nums[beforeSecond]!=nums[second]){
                       List<Integer> rAns = new ArrayList<Integer>();
                       rAns.add(nums[first]);
                       rAns.add(nums[second]);
                       rAns.add(nums[third]);
                       ans.add(rAns);
                   }
                   beforeSecond = second;
                   ++second;
                   --third;
                   continue;
               }
               if(nums[second]+nums[third]>target){
                   --third;
               }else{
                   ++second;
               }
           }
        }
        return ans;
    }
}

 17.电话号码的字母组合

      回溯算法

public List<String> letterCombinations(String digits) {
        List<String> combinations = new ArrayList<String>();
        if(digits == null || digits.length() == 0){
            return combinations;
        }

        Map<Character,String> digitsMap = new HashMap<Character,String>();
        digitsMap.put('2',"abc");
        digitsMap.put('3',"def");
        digitsMap.put('4',"ghi");
        digitsMap.put('5',"jkl");
        digitsMap.put('6',"mno");
        digitsMap.put('7',"pqrs");
        digitsMap.put('8',"tuv");
        digitsMap.put('9',"wxyz");

        getCharacterGroup(combinations,digitsMap,digits,0,new StringBuilder());
        return combinations;

    }

    public void getCharacterGroup(List<String> combinations,Map<Character,String> digitsMap,String digits,int index,StringBuilder combination){
        if(index == digits.length()){
            combinations.add(combination.toString());
            return;
        }

        Character digit = digits.charAt(index);
        String digitMap = digitsMap.get(digit);
        int digitCount = digitMap.length();
        for(int i = 0;i<digitCount;++i){
            combination.append(digitMap.charAt(i));
            getCharacterGroup(combinations,digitsMap,digits,index+1,combination);
            combination.deleteCharAt(index);
        }
    }

 22、括号生成

  回溯算法

描述: 数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。

输入:n = 3
输出:["((()))","(()())","(())()","()(())","()()()"]

class Solution {
    public List<String> generateParenthesis(int n) {
        List<String> ans  = new ArrayList<String>();
        getPatenthesis(ans,new StringBuilder(),0,0,n);
        return ans;
        
    }
    public void getPatenthesis(List<String> ans , StringBuilder str , int open, int close,int max){
        if(str.length() == 2*max){
            if(open == close){
                ans.add(str.toString());
            }
            return;
        }

        str.append('(');
        getPatenthesis(ans,str,open+1,close,max);
        str.deleteCharAt(str.length()-1);

        if(close<open){
            str.append(')');
            getPatenthesis(ans,str,open,close+1,max);
            str.deleteCharAt(str.length()-1);
        }
    }
}
31. 下一个排序
描述:

  实现获取 下一个排列 的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列(即,组合出下一个更大的整数)。

  如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。

class Solution {
    public void nextPermutation(int[] nums) {
        int nLen = nums.length;
        int i = nLen - 2;
        while(i>=0 && nums[i]>= nums[i+1]){
            --i;
        }

        if(i>=0){
            int j = nLen-1;
            while(j>i && nums[j]<=nums[i]){
                --j;
            }
            if(j>=0){
                swap(nums,i,j);
                reverse(nums,i+1);
            }
        }else{
            reverse(nums,0);
        }
    }

    public void swap(int[] nums,int i , int j){
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
    
    public void reverse(int[] nums , int start){
        int end  = nums.length-1;
        int temp ;
        while(start<end){
            temp = nums[end];
            nums[end] = nums[start];
            nums[start] = temp;
            ++start;
            --end;
        }
    }
}

32. 最长有效括号

     动态规划

描述:

给你一个只包含 '(' 和 ')' 的字符串,找出最长有效(格式正确且连续)括号子串的长度。

class Solution {
    public int longestValidParentheses(String s) {
        int sLen = s.length();
        int[] dp = new int[sLen];

        int max = 0;
        for(int i = 1; i < sLen; ++i){
            if(s.charAt(i) == ')'){
                if(s.charAt(i-1) == '('){
                    dp[i] =(i>=2?dp[i-2]:0)+2;
                }else{
                    if(i-dp[i-1]>0 && s.charAt(i-dp[i-1]-1)=='('){
                        dp[i] = (i-dp[i-1]-2>=0?dp[i-dp[i-1]-2]:0)+dp[i-1]+2;
                    }
                }
                max = Math.max(max,dp[i]);
            }
        }

        return max;
    }
}

34 在排序数组中查找元素的第一个和最后一个位置

  二分查找算法

39. 组合总和

  搜索回溯算法

描述:
给定一个无重复元素的正整数数组 candidates 和一个正整数 target ,找出 candidates 中所有可以使数字和为目标数 target 的唯一组合。candidates 中的数字可以无限制重复被选取。如果至少一个所选数字数量不同,则两种组合是唯一的。 
class Solution {
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        List<List<Integer>> ans = new ArrayList<List<Integer>>();
        getSum(candidates,ans,new ArrayList<Integer>() , 0, target);
        return ans;
    }
    public void getSum(int[] candidates,List<List<Integer>> ans , List<Integer> res , int index , int target){
        if(index>candidates.length-1){
            return;
        }

        if(target == 0){
            ans.add(new ArrayList<Integer>(res));  // 注意要new新对象
            return;
        }

        if(target>=candidates[index]){
            res.add(candidates[index]);
            getSum(candidates,ans,res,index,target-candidates[index]);
            res.remove(res.size()-1);
            getSum(candidates,ans,res,index+1,target);
        }else{
            getSum(candidates,ans,res,index+1,target);
        }
    }
}

42. 接雨水 

   双指针

描述:给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

class Solution {
    public int trap(int[] height) {
        int hLen = height.length;

        int[] left = new int[hLen];
        int[] right = new int[hLen];

        left[0] = -1;
        right[hLen-1] = -1;

        int maxLeft = height[0];
        for(int i = 1;i<hLen;++i){
            if(height[i]>=maxLeft){
                left[i] = -1;
                maxLeft = height[i];
            }else{
                left[i] = maxLeft;
            }
        }
        int maxRight = height[hLen-1];
        for(int i =hLen-2 ; i>=0 ; --i){
            if(height[i]>=maxRight){
                right[i] = -1;
                maxRight = height[i];
            }else{
                right[i] = maxRight;
            }
        }

        int sum = 0;
        for(int i = 1;i<hLen-1;i++){
            if(left[i] !=-1 && right[i]!=-1){
                sum = sum + Math.min(left[i],right[i])-height[i];
            }
        }
        return sum;
    }
}

 





 

 

str.append('l');
str.deleteCharAt(1);
List<String> ans = new ArrayList<String>();
ans.add(str.toString());

posted @ 2021-10-21 14:25  微~粒  阅读(34)  评论(0)    收藏  举报