leetcode难题集合

3.无重复字符的最长子串

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

    }

4寻找两个正序数组的中位数

public class Solution {
    public static double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int length1 = nums1.length, length2 = nums2.length;
        int totalLength = length1 + length2;
        if (totalLength % 2 == 1) {
            int midIndex = totalLength / 2;
            double median = getKthElement(nums1, nums2, midIndex + 1);
            return median;
        } else {
            int midIndex1 = totalLength / 2 - 1, midIndex2 = totalLength / 2;
            double median = (getKthElement(nums1, nums2, midIndex1 + 1) + getKthElement(nums1, nums2, midIndex2 + 1)) / 2.0;
            return median;
        }
    }

    public static int getKthElement(int[] nums1, int[] nums2, int k) {

        int length1 = nums1.length, length2 = nums2.length;
        int index1 = 0, index2 = 0;
        int kthElement = 0;

        while (true) {
            // 边界情况
            if (index1 == length1) {
                return nums2[index2 + k - 1];
            }
            if (index2 == length2) {
                return nums1[index1 + k - 1];
            }
            if (k == 1) {
                return Math.min(nums1[index1], nums2[index2]);
            }

            // 正常情况
            int half = k / 2;
            int newIndex1 = Math.min(index1 + half, length1) - 1;
            int newIndex2 = Math.min(index2 + half, length2) - 1;
            int pivot1 = nums1[newIndex1], pivot2 = nums2[newIndex2];
            if (pivot1 <= pivot2) {
                k -= (newIndex1 - index1 + 1);
                index1 = newIndex1 + 1;
            } else {
                k -= (newIndex2 - index2 + 1);
                index2 = newIndex2 + 1;
            }
        }
    }

    public static void main(String[] args) {
        int [] nums1 = {1,2};
        int [] nums2 = {3,4,5};
        System.out.println(findMedianSortedArrays(nums1,nums2));
    }
}

5最长回文子串

public class LK005 {
    public static int isPalindrome(int L, String str) {
        for (int i = 0; i < str.length()- L + 1; i++) {
            String s1 = str.substring(i,i+L);
            String s2 = reverse(s1);
            if(s1.equals(s2)) {
                return i;
            }
        }
        return -1;
    }

    public static String longestPalindrome(String s) {
        int left = 1,right = s.length();
        while (left != right) {
            int mid = (right-left)/2 +left;
            if(isPalindrome(mid,s) == -1) {
                right = mid-1;
            } else {
                left = mid;
            }
        }
        int start = isPalindrome(left,s);
        return  s.substring(start,start + left);
    }
    public static String reverse(String str) {
        StringBuilder sb = new StringBuilder();
        for (int i = str.length()-1; i >= 0; i--) {
            sb.append(String.valueOf(str.charAt(i)));
        }
        return sb.toString();
    }

    public static void main(String[] args) {

        System.out.println(longestPalindrome("aabccbabab"));
    }
}

6Z字型变换

public class Solution {
    public static String convert(String s, int numRows) {

        if (numRows == 1) return s;

        List<StringBuilder> rows = new ArrayList<>();
        for (int i = 0; i < Math.min(numRows, s.length()); i++)
            rows.add(new StringBuilder());

        int curRow = 0;
        boolean goingDown = false;

        for (char c : s.toCharArray()) {
            rows.get(curRow).append(c);
            if (curRow == 0 || curRow == numRows - 1) goingDown = !goingDown;
            curRow += goingDown ? 1 : -1;
        }

        StringBuilder ret = new StringBuilder();
        for (StringBuilder row : rows) ret.append(row);

        return ret.toString();


    }

    public static void main(String[] args) {
        System.out.println(convert("LEETCODEISHIRING",4));
    }
}

10正则表达式

public class Solution {
    public static boolean isMatch(String s, String p) {
        int m = s.length();
        int n = p.length();

        boolean[][] f = new boolean[m + 1][n + 1];
        f[0][0] = true;
        for (int i = 0; i <= m; ++i) {
            for (int j = 1; j <= n; ++j) {
                if (p.charAt(j - 1) == '*') {
                    f[i][j] = f[i][j - 2];
                    boolean flag = matches(s, p, i, j - 1);
                    if (flag) {
                        f[i][j] = f[i][j] || f[i - 1][j];
                    }
                }
                else {
                    boolean flag = matches(s, p, i, j);
                    if (matches(s, p, i, j)) {
                        f[i][j] = f[i - 1][j - 1];
                    }
                }
            }
        }
        return f[m][n];
    }

    public static boolean matches(String s, String p, int i, int j) {
        if (i == 0) {
            return false;
        }
        if (p.charAt(j - 1) == '.') {
            return true;
        }
        return s.charAt(i - 1) == p.charAt(j - 1);
    }


    public static void main(String[] args) {

        System.out.println(isMatch("ab",".*"));
    }
}

15三数之和

package com.niukeoffer.a000LiKou.LK015三数之和;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Solution {
    public static List<List<Integer>> threeSum(int[] nums) {
        int n = nums.length;
        Arrays.sort(nums);
        List<List<Integer>> ans = new ArrayList<List<Integer>>();
        // 枚举 a
        for (int first = 0; first < n; ++first) {
            // 需要和上一次枚举的数不相同
            if (first > 0 && nums[first] == nums[first - 1]) {
                continue;
            }
            // c 对应的指针初始指向数组的最右端
            int third = n - 1;
            int target = -nums[first];
            // 枚举 b
            for (int second = first + 1; second < n; ++second) {
                // 需要和上一次枚举的数不相同
                if (second > first + 1 && nums[second] == nums[second - 1]) {
                    continue;
                }
                // 需要保证 b 的指针在 c 的指针的左侧
                while (second < third && nums[second] + nums[third] > target) {
                    --third;
                }
                // 如果指针重合,随着 b 后续的增加
                // 就不会有满足 a+b+c=0 并且 b<c 的 c 了,可以退出循环
                if (second == third) {
                    break;
                }
                if (nums[second] + nums[third] == target) {
                    List<Integer> list = new ArrayList<Integer>();
                    list.add(nums[first]);
                    list.add(nums[second]);
                    list.add(nums[third]);
                    ans.add(list);
                }
            }
        }
        return ans;
    }

    public static void main(String[] args) {
        int [] nums ={-1,0,1,2,-1,4};
        threeSum(nums);
        for (int i = 0; i < 1; i++) {
            for (int j = 0; j < 1; j++) {

            }
        }
        System.out.println();
    }

}

16最接近的三个数之和

package com.niukeoffer.a000LiKou.LK016最接近的三个数之和;

import java.util.Arrays;

public class Solution {
    public static int threeSumClosest(int[] nums, int target) {
        Arrays.sort(nums);
        int ans = nums[0] + nums[1] + nums[2];
        for(int i=0;i<nums.length;i++) {
            int start = i+1, end = nums.length - 1;
            while(start < end) {
                int sum = nums[start] + nums[end] + nums[i];
                if(Math.abs(target - sum) < Math.abs(target - ans))
                    ans = sum;
                if(sum > target)
                    end--;
                else if(sum < target)
                    start++;
                else
                    return ans;
            }
        }
        return ans;
    }

    public static void main(String[] args) {
        int [] nums = {-1,2,1,-4};
        threeSumClosest(nums,2);
    }
}

23合并K个升序链表

package com.niukeoffer.a000LiKou.LK023合并K个升序链表;


class ListNode {
    int val;
    ListNode next;
    ListNode() {}
    ListNode(int val) { this.val = val; }
    ListNode(int val, ListNode next) { this.val = val; this.next = next; }
}
public class Solution {
    public static ListNode mergeKLists(ListNode[] lists) {
        if (lists == null || lists.length == 0) return null;
        return merge(lists, 0, lists.length - 1);
    }

    private static ListNode merge(ListNode[] lists, int left, int right) {
        if (left == right) return lists[left];
        int mid = left + (right - left) / 2;
        ListNode l1 = merge(lists, left, mid);
        ListNode l2 = merge(lists, mid + 1, right);
        return mergeTwoLists(l1, l2);
    }

    private static ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        if (l1 == null) return l2;
        if (l2 == null) return l1;
        if (l1.val < l2.val) {
            l1.next = mergeTwoLists(l1.next, l2);
            return l1;
        } else {
            l2.next = mergeTwoLists(l1,l2.next);
            return l2;
        }
    }


    public static void main(String[] args) {
        ListNode p3 = new ListNode(5);
        ListNode p2 = new ListNode(4,p3);
        ListNode p1 = new ListNode(1,p2);

        ListNode q3 = new ListNode(4);
        ListNode q2 = new ListNode(3,q3);
        ListNode q1 = new ListNode(1,q2);


        ListNode r2 = new ListNode(6);
        ListNode r1 = new ListNode(2,r2);

        ListNode[] list = {r1,q1,p1};
        System.out.println(mergeKLists(list));
    }

}

25K个一组翻转链表

package com.niukeoffer.a000LiKou.LK025K个一组翻转链表;

class ListNode {
    int val;
    ListNode next;
    ListNode(int x) { val = x; }
}

public class Solution {
    public static ListNode reverseKGroup(ListNode head, int k) {
        ListNode dummy = new ListNode(0);
        dummy.next = head;

        ListNode pre = dummy;
        ListNode end = dummy;

        while (end.next != null) {
            for (int i = 0; i < k && end != null; i++) end = end.next;
            if (end == null) break;
            ListNode start = pre.next;
            ListNode next = end.next;
            end.next = null;
            pre.next = reverse(start);
            start.next = next;
            pre = start;

            end = pre;
        }
        return dummy.next;
    }

    private static ListNode reverse(ListNode head) {
        ListNode pre = null;
        ListNode curr = head;
        while (curr != null) {
            ListNode next = curr.next;
            curr.next = pre;
            pre = curr;
            curr = next;
        }
        return pre;
    }

    public static void main(String[] args) {
        ListNode p1 = new ListNode(1);
        ListNode p2 = new ListNode(2);
        ListNode p3 = new ListNode(3);
        ListNode p4 = new ListNode(4);
        ListNode p5 = new ListNode(5);
        p1.next=p2; p2.next=p3; p3.next=p4; p4.next=p5;
        System.out.println(reverseKGroup(p1,3));

    }

}

30串联所有单词的子串

package com.niukeoffer.a000LiKou.LK030串联所有单词的子串;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Test {
    public static List<Integer> findSubstring(String s, String[] words) {
        List<Integer> list = new ArrayList<>();
        Map<String,Integer> map1 = new HashMap<>();

        int len=words[0].length();
        int num = words.length;
        int all_len = num*len;
        for(String word:words) {
            map1.put(word,map1.getOrDefault(word,0)+1);
        }
        int count=0;
        for (int i = 0; i < s.length()-all_len; i=i+len) {
            System.out.println();
            Map<String,Integer> map2 = new HashMap<>();
            for (int j = i; j < i+all_len; j=j+len) {
                String temp = s.substring(j,j+len);
                map2.put(temp,map2.getOrDefault(temp,0)+1);
            }
            if(map2.equals(map1)) {
                list.add(i);
            }
        }
        return list;
    }

    public static void main(String[] args) {
        String [] words = {"word","good","best","word"};
        List<Integer> list = findSubstring("wordgoodgoodgoodbestword",words);
        System.out.println(list.size());
    }
}

31下一个排序

package com.niukeoffer.a000LiKou.LK031下一个排序;

public class Test {
    public static void nextPermutation(int[] nums) {
        int loc = nums.length-2,endloc=nums.length-1;
        for (int i = nums.length-2; i >=0 ; i--) {
            if(nums[i]<nums[i+1]) {
                loc=i;
                for (int j = nums.length-1; j >loc ; j--) {
                    if(nums[j]>nums[loc]) {
                        endloc=j;
                        break;
                    }
                }
                swap(nums,loc,endloc);
                reverse(nums,loc+1,nums.length-1);
                return;
            }
            if(i==0) {
                reverse(nums,0,nums.length-1);
                return;
            }
        }

    }
    public static void swap(int [] nums,int i,int j) {
        int temp = nums[i];
        nums[i]=nums[j];
        nums[j]=temp;
    }
    public static void reverse(int [] nums,int left,int right) {
        while (left<right) {
            swap(nums,left,right);
            left++;
            right--;
        }
    }

    public static void main(String[] args) {
        int [] nums ={1,1,1,4,3,2,1};
        nextPermutation(nums);
        for (int i = 0; i < nums.length; i++) {
            System.out.print(nums[i]+" ");
        }
    }
}

32最长有效括号

package com.niukeoffer.a000LiKou.LK032最长有效括号;

import java.util.Stack;

public class Test {
    public static int longestValidParentheses(String s) {
        Stack<Integer> stack = new Stack<>();
        stack.add(-1);
        int max=0;
        for (int i = 0; i < s.length(); i++) {
            if(s.charAt(i)==')') {
                if(stack.peek()==-1) {
                    stack.add(i);
                } else {
                    char c = s.charAt(stack.peek());
                    if(c=='(') {
                        stack.pop();
                    } else {
                        stack.push(i);
                    }
                    max=Math.max(max,i-stack.peek());
                }
            } else {
                stack.add(i);
            }
        }
        return max;
    }
    public static void main(String[] args) {
//        Stack<Integer> stack = new Stack<>();
//        System.out.println(stack.peek());
        System.out.println(longestValidParentheses("()(()(()()"));
    }
}

37解数独

package com.niukeoffer.a000LiKou.LK037解数独;

import java.util.ArrayList;
import java.util.List;

class Solution {
    private static boolean[][] line = new boolean[9][9];
    private static boolean[][] column = new boolean[9][9];
    private static boolean[][][] block = new boolean[3][3][9];
    private static boolean valid = false;
    private static List<int[]> spaces = new ArrayList<int[]>();

    public static void solveSudoku(char[][] board) {
        for (int i = 0; i < 9; ++i) {
            for (int j = 0; j < 9; ++j) {
                if (board[i][j] == '.') {
                    spaces.add(new int[]{i, j});
                } else {
                    int digit = board[i][j] - '0' - 1;
                    line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = true;
                }
            }
        }

        dfs(board, 0);
    }

    public static void dfs(char[][] board, int pos) {
        if (pos == spaces.size()) {
            valid = true;
            return;
        }

        int[] space = spaces.get(pos);
        int i = space[0], j = space[1];
        for (int digit = 0; digit < 9 && !valid; ++digit) {
            if (!line[i][digit] && !column[j][digit] && !block[i / 3][j / 3][digit]) {
                line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = true;
                board[i][j] = (char) (digit + '0' + 1);
                dfs(board, pos + 1);
                line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = false;
            }
        }
    }

    public static void main(String[] args) {

    }
}


41缺失的第一个整数

package com.niukeoffer.a000LiKou.LK041缺失的第一个整数;

public class Test {
    public static int firstMissingPositive(int[] nums) {
        for (int i = 0; i < nums.length; i++) {
            if(nums[i]<=0) {
                nums[i]=Integer.MAX_VALUE;
            }
        }
        for (int i = 0; i < nums.length; i++) {
            if(nums[i]<=nums.length) {
                nums[nums[i]-1] *= -1;
            }
        }
        for (int i = 0; i < nums.length; i++) {
            if(nums[i]> 0 ) {
                return i+1;
            }
        }
        return nums.length+1;
    }

    public static void main(String[] args) {
        int [] nums ={1,-1,3,4};
        System.out.println(firstMissingPositive(nums));
    }
}

42接雨水

package com.niukeoffer.a000LiKou.LK042接雨水;

import java.util.Stack;

public class Test {
    public static int trap(int[] height) {
        int sum=0;
        Stack<Integer> stack = new Stack<>();
        for (int i = 0; i < height.length; i++) {
            if(stack.isEmpty()) {
                stack.add(i);
            } else {
                int floor=0;
                while (!stack.isEmpty() && height[stack.peek()] < height[i]) {
                    int top = stack.pop();
                    sum+=(Math.min(height[stack.peek()],height[i])-height[top])*(i-stack.peek()-1);
                }
                stack.add(i);
            }
        }
        return sum;
    }

    public static void main(String[] args) {
        int [] nums={4,1,0,2,1,4};
        System.out.println(trap(nums));
    }
}

43字符串相乘

package com.niukeoffer.a000LiKou.LK043字符串相乘;

public class Test {
    public static String multiply(String num1, String num2) {
        String res = "0";
        int len1=num1.length(),len2=num2.length();
        for (int i = len1-1; i >= 0; i--) {
            StringBuilder temp = new StringBuilder();
            for (int j = i; j <len1-1 ; j++) {
                temp.append('0');
            }
            int count=0;
            int x = num1.charAt(i)-'0';
            for (int j = len2-1; j >= 0 || count!=0; j--) {
                int y = j<0 ?0:num2.charAt(j)-'0';
                int proc = (x*y + count) %10;
                temp.append(proc);
                count=(x*y+count)/10;
            }
            res = add(res,temp.reverse().toString());
        }
        return res;
    }

    public static String add(String num1, String num2) {
        int len1=num1.length(),len2=num2.length();
        StringBuilder sb = new StringBuilder();
        int count=0;
        for (int i = len1-1, j=len2-1; i >=0 ||j>=0 || count!=0 ; i--,j--) {
            int x = i<0 ? 0: num1.charAt(i)-'0';
            int y = j<0 ? 0:num2.charAt(j)-'0';
            int proc = (x+y+count)%10;
            sb.append(proc);
            count = (x+y+count)/10;
        }
        return sb.reverse().toString();
    }

    public static void main(String[] args) {
        System.out.println(multiply("125","125"));
    }
}

45跳跃游戏

package com.niukeoffer.a000LiKou.LK045跳跃游戏;

import java.util.Arrays;

public class Solution {
    public int jump(int[] nums) {
        int [] f= new int[nums.length];

        Arrays.fill(f,Integer.MAX_VALUE);
        f[0]=0;

        for(int i=0;i<nums.length;i++) {
            for(int j=1;j<=nums[i];j++) {
                if(i+j<nums.length) {
                    f[i+j] = Math.min(f[i+j],f[i]+1);
                }
            }
        }
        return f[nums.length-1];
    }
}

47全排列2

package com.niukeoffer.a000LiKou.LK047全排列2;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Test {
    static List<List<Integer>> res = new ArrayList<>();
    public static List<List<Integer>> permuteUnique(int[] nums) {
        Arrays.sort(nums);
        permute(nums,0);
        return res;
    }
    public static void permute(int [] nums,int loc) {
        if(loc==nums.length-1) {
            List<Integer> list = new ArrayList<>();
            for (int i = 0; i < nums.length; i++) {
                list.add(nums[i]);
            }
            res.add(list);
        }
        for (int i = loc; i < nums.length; i++) {
            if(i==loc || (i>loc && nums[i]!=nums[i-1])) {
                swap(nums,loc,i);
                permute(nums,loc+1);
                swap(nums,loc,i);
            }

        }
    }
    public static void swap(int [] nums,int i,int j) {
        int temp = nums[i];
        nums[i]=nums[j];
        nums[j]=temp;
    }
    public static void main(String[] args) {
        int [] nums ={1,1,1,2,2};
        permuteUnique(nums);
        System.out.println(res.size());
    }
}

51N皇后

package com.niukeoffer.a000LiKou.LK051N皇后;

import java.util.*;

public class Solution {
    static int rows[];
    // "hill" diagonals
    static int hills[];
    // "dale" diagonals
    static int dales[];
    static int n;
    // output
    static List<List<String>> output = new ArrayList();
    // queens positions
    static int queens[];

    public static boolean isNotUnderAttack(int row, int col) {
        int a = rows[col],b=hills[row - col + 2 * n],c=dales[row + col];
        int res = a + b + c;
        return (res == 0) ? true : false;
    }

    public static void placeQueen(int row, int col) {
        queens[row] = col;
        rows[col] = 1;
        hills[row - col + 2 * n] = 1;  // "hill" diagonals
        dales[row + col] = 1;   //"dale" diagonals
    }

    public static void removeQueen(int row, int col) {
        queens[row] = 0;
        rows[col] = 0;
        hills[row - col + 2 * n] = 0;
        dales[row + col] = 0;
    }

    public static void addSolution() {
        List<String> solution = new ArrayList<String>();
        for (int i = 0; i < n; ++i) {
            int col = queens[i];
            StringBuilder sb = new StringBuilder();
            for(int j = 0; j < col; ++j) sb.append(".");
            sb.append("Q");
            for(int j = 0; j < n - col - 1; ++j) sb.append(".");
            solution.add(sb.toString());
        }
        output.add(solution);
    }

    public static void backtrack(int row) {
        for (int col = 0; col < n; col++) {
            if (isNotUnderAttack(row, col)) {
                placeQueen(row, col);
                // if n queens are already placed
                if (row + 1 == n) addSolution();
                    // if not proceed to place the rest
                else backtrack(row + 1);
                // backtrack
                removeQueen(row, col);
            }
        }
    }

    public static List<List<String>> solveNQueens(int nn) {
        n = nn;
        rows = new int[nn];
        hills = new int[4 * nn - 1];
        dales = new int[2 * nn - 1];
        queens = new int[nn];

        backtrack(0);
        return output;
    }

    public static void main(String[] args) {
        List<List<String>> list = solveNQueens(5);
        for (int i = 0; i < list.size(); i++) {
            for (int j = 0; j < list.get(i).size(); j++) {
                System.out.println(list.get(i).get(j));
            }
            System.out.println();
        }
    }


}

52N皇后2

57插入区间

package com.niukeoffer.a000LiKou.LK057插入区间;

import java.util.ArrayList;
import java.util.Comparator;

public class Test {
    public static int[][] insert(int[][] intervals, int[] newInterval) {
        ArrayList<int []> list = new ArrayList<>();
        for (int i = 0; i < intervals.length; i++) {
            list.add(intervals[i]);
        }
        list.add(newInterval);
        list.sort(new Comparator<int[]>() {
            @Override
            public int compare(int[] o1, int[] o2) {
                return o1[0]-o2[0];
            }
        });

        int loc=0,left=Integer.MAX_VALUE, right=Integer.MIN_VALUE;
        ArrayList<int []> res = new ArrayList<>();
        while (loc<list.size()) {
            left=Math.min(left,list.get(loc)[0]);
            right=Math.max(right,list.get(loc)[1]);
            if(loc+1<=list.size()-1 && right>=list.get(loc+1)[0]) {
                loc++;
                continue;
            } else {
                res.add(new int[]{left,right});
                left=Integer.MAX_VALUE;
                right=Integer.MIN_VALUE;
                loc++;
            }

        }
        int [][] nums = new int[res.size()][2];
        for (int i = 0; i < res.size(); i++) {
            nums[i][0]=res.get(i)[0];
            nums[i][1]=res.get(i)[1];
        }
        return nums;
    }

    public static void main(String[] args) {
        int [][] intervals = {{1,3},{2,5},{6,9},{11,25}};
        int [] newInterval = {2,6};
        intervals=insert(intervals,newInterval);
        for (int i = 0; i < intervals.length; i++) {
            for (int j = 0; j < 2; j++) {
                System.out.print(intervals[i][j]+" ");
            }
            System.out.println();
        }
    }
}

60第k个排列

package com.niukeoffer.a000LiKou.LK060第k个排列;

import java.util.Arrays;

class Solution {
    public static String getPermutation(int n, int k) {
        int[] factorial = new int[n];
        factorial[0] = 1;
        for (int i = 1; i < n; ++i) {
            factorial[i] = factorial[i - 1] * i;
        }

        --k;
        StringBuffer ans = new StringBuffer();
        int[] valid = new int[n + 1];

        Arrays.fill(valid, 1);
        for (int i = 1; i <= n; ++i) {
            int order = k / factorial[n - i] + 1;
            for (int j = 1; j <= n; ++j) {
                order -= valid[j];
                if (order == 0) {
                    ans.append(j);
                    valid[j] = 0;
                    break;
                }
            }
            k %= factorial[n - i];
        }
        return ans.toString();
    }

    public static void main(String[] args) {
        System.out.println(getPermutation(3,3));
    }
}


65有效数字

68文本左右对齐

72编辑距离

package com.niukeoffer.a000LiKou.LK072编辑距离;

public class Solution {
    public static int minDistance(String word1, String word2) {
        int n = word1.length();
        int m = word2.length();

        // 有一个字符串为空串
        if (n * m == 0)
            return n + m;

        // DP 数组
        int [][] D = new int[n + 1][m + 1];

        // 边界状态初始化
        for (int i = 0; i < n + 1; i++) {
            D[i][0] = i;
        }
        for (int j = 0; j < m + 1; j++) {
            D[0][j] = j;
        }

        // 计算所有 DP 值
        for (int i = 1; i < n + 1; i++) {
            for (int j = 1; j < m + 1; j++) {
                int left = D[i - 1][j] + 1;
                int down = D[i][j - 1] + 1;
                int left_down = D[i - 1][j - 1];
                if (word1.charAt(i - 1) != word2.charAt(j - 1))
                    left_down += 1;
                D[i][j] = Math.min(left, Math.min(down, left_down));

            }
        }
        return D[n][m];
    }

    public static void main(String[] args) {
        System.out.println(minDistance("ab","cd"));
    }

}

76最小覆盖子串

package com.niukeoffer.a000LiKou.LK076最小覆盖子串;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class Main {
    static Map<Character, Integer> ori = new HashMap<Character, Integer>();
    static Map<Character, Integer> cnt = new HashMap<Character, Integer>();

    public static String minWindow(String s, String t) {
        int tLen = t.length();
        for (int i = 0; i < tLen; i++) {
            char c = t.charAt(i);
            ori.put(c, ori.getOrDefault(c, 0) + 1);
        }
        int l = 0, r = -1;
        int len = Integer.MAX_VALUE, ansL = -1, ansR = -1;
        int sLen = s.length();
        while (r < sLen) {
            ++r;
            if (r < sLen && ori.containsKey(s.charAt(r))) {
                cnt.put(s.charAt(r), cnt.getOrDefault(s.charAt(r), 0) + 1);
            }
            while (check() && l <= r) {
                if (r - l + 1 < len) {
                    len = r - l + 1;
                    ansL = l;
                    ansR = l + len;
                }
                if (ori.containsKey(s.charAt(l))) {
                    cnt.put(s.charAt(l), cnt.getOrDefault(s.charAt(l), 0) - 1);
                }
                ++l;
            }
        }
        return ansL == -1 ? "" : s.substring(ansL, ansR);
    }

    public static boolean check() {
        Iterator iter = ori.entrySet().iterator();
        while (iter.hasNext()) {
            Map.Entry entry = (Map.Entry) iter.next();
            Character key = (Character) entry.getKey();
            Integer val = (Integer) entry.getValue();
            if (cnt.getOrDefault(key, 0) < val) {
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args) {
        System.out.println(minWindow("adobecodebanc","abc"));
    }
}



84柱形图中最大的矩形

package com.niukeoffer.a000LiKou.LK084柱形图中最大的矩形;

import java.util.Arrays;
import java.util.Stack;

public class Solution {
    public static int largestRectangleArea(int[] heights) {
        int n = heights.length;
        int[] left = new int[n];
        int[] right = new int[n];
        Arrays.fill(right, n);

        Stack<Integer> mono_stack = new Stack<Integer>();
        for (int i = 0; i < n; ++i) {
            while (!mono_stack.isEmpty() && heights[mono_stack.peek()] >= heights[i]) {
                right[mono_stack.peek()] = i;
                mono_stack.pop();
            }
            left[i] = (mono_stack.isEmpty() ? -1 : mono_stack.peek());
            mono_stack.push(i);
        }
        int ans = 0;
        for (int i = 0; i < n; ++i) {
            ans = Math.max(ans, (right[i] - left[i] - 1) * heights[i]);
        }
        return ans;
    }
    public static void main(String[] args) {
        int [] nums ={2,1,5,6,2,3};
        System.out.println(largestRectangleArea(nums));
    }
}

85最大矩形

package com.niukeoffer.a000LiKou.LK085最大矩形;

import java.util.Arrays;

public class Solution {
    public static int maximalRectangle(char[][] matrix) {
        if(matrix.length == 0) return 0;
        int m = matrix.length;
        int n = matrix[0].length;

        int[] left = new int[n]; // initialize left as the leftmost boundary possible
        int[] right = new int[n];
        int[] height = new int[n];

        Arrays.fill(right, n); // initialize right as the rightmost boundary possible

        int maxarea = 0;
        for(int i = 0; i < m; i++) {
            int cur_left = 0, cur_right = n;
            // update height
            for (int j = 0; j < n; j++) {
                if (matrix[i][j] == '1') height[j]++;
                else height[j] = 0;
            }
            // update left
            for (int j = 0; j < n; j++) {
                if (matrix[i][j] == '1') left[j] = Math.max(left[j], cur_left);
                else {
                    left[j] = 0;
                    cur_left = j + 1;
                }
            }
            // update right
            for (int j = n - 1; j >= 0; j--) {
                if (matrix[i][j] == '1') right[j] = Math.min(right[j], cur_right);
                else {
                    right[j] = n;
                    cur_right = j;
                }
            }
            // update area
            for (int j = 0; j < n; j++) {
                int temp =(right[j] - left[j]) * height[j];
                maxarea = Math.max(maxarea, temp);
            }
        }
        return maxarea;
    }

    public static void main(String[] args) {
        char [][] nums ={{'1','0','1','0','0'},
                {'1','0','1','1','1'},
                {'1','1','1','1','1'},
                {'1','0','0','1','0'}};
        System.out.println(maximalRectangle(nums));
    }
}

87扰乱字符串

package com.niukeoffer.a000LiKou.LK087扰乱字符串;

public class Solution {
    public static boolean isScramble(String s1, String s2) {
        if (s1.length() != s2.length()) {
            return false;
        }
        if (s1.equals(s2)) {
            return true;
        }

        //判断两个字符串每个字母出现的次数是否一致
        int[] letters = new int[26];
        for (int i = 0; i < s1.length(); i++) {
            letters[s1.charAt(i) - 'a']++;
            letters[s2.charAt(i) - 'a']--;
        }
        //如果两个字符串的字母出现不一致直接返回 false
        for (int i = 0; i < 26; i++) {
            if (letters[i] != 0) {
                return false;
            }
        }

        //遍历每个切割位置
        for (int i = 1; i < s1.length(); i++) {
            //对应情况 1 ,判断 S1 的子树能否变为 S2 相应部分
            if (isScramble(s1.substring(0, i), s2.substring(0, i)) && isScramble(s1.substring(i), s2.substring(i))) {
                return true;
            }
            //对应情况 2 ,S1 两个子树先进行了交换,然后判断 S1 的子树能否变为 S2 相应部分
            if (isScramble(s1.substring(i), s2.substring(0, s2.length() - i)) &&
                    isScramble(s1.substring(0, i), s2.substring(s2.length() - i)) ) {
                return true;
            }
        }
        return false;
    }

    public static void main(String[] args) {
        System.out.println(isScramble("great","rgeat"));
    }

}

97交错字符串

package com.niukeoffer.a000LiKou.LK097交错字符串;

public class MyTest {
    public static boolean isInterleave(String s1, String s2, String s3) {
        if(s1.length()+s2.length() != s3.length()) {
            return false;
        }
        int max=Integer.MAX_VALUE;
        return Interleave(s1,s2,s3);
    }
    public static boolean Interleave(String s1, String s2, String s3) {
        if(s3.length() == 0)  return true;
        if(s1.length() == 0)  return s2.equals(s3);
        if(s2.length() == 0)  return s1.equals(s3);
        if(s1.charAt(0) == s3.charAt(0) && s2.charAt(0)==s3.charAt(0)) {
            return Interleave(s1.substring(1,s1.length()),s2,s3.substring(1,s3.length())) ||
                    Interleave(s1,s2.substring(1,s2.length()),s3.substring(1,s3.length()));
        } else if(s1.charAt(0) == s3.charAt(0)) {
            return Interleave(s1.substring(1,s1.length()),s2,s3.substring(1,s3.length()));
        } else if(s2.charAt(0)==s3.charAt(0)) {
            return Interleave(s1,s2.substring(1,s2.length()),s3.substring(1,s3.length()));
        } else {
            return false;
        }
    }

    public static void main(String[] args) {
        System.out.println(isInterleave("aaaaa","aaaaa","aaaaaaaaaa"));
    }


}

99恢复二叉搜索树

128最长连续序列

package com.niukeoffer.a000LiKou.LK128最长连续序列;

import java.util.HashSet;
import java.util.Set;

public class Solution {
    public static int longestConsecutive(int[] nums) {
        Set<Integer> num_set = new HashSet<Integer>();
        for (int num : nums) {
            num_set.add(num);
        }

        int longestStreak = 0;

        for (int num : num_set) {
            if (!num_set.contains(num - 1)) {
                int currentNum = num;
                int currentStreak = 1;

                while (num_set.contains(currentNum + 1)) {
                    currentNum += 1;
                    currentStreak += 1;
                }

                longestStreak = Math.max(longestStreak, currentStreak);
            }
        }

        return longestStreak;
    }


    public static void main(String[] args) {

        int [] nums = {1,2,100,3,4};
        System.out.println(longestConsecutive(nums));
    }
}

146LRU的缓存机制

package com.niukeoffer.a000LiKou.LK146LRU的缓存机制;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class LRUCache<V> {

    /**
     * 容量
     */
    private int capacity = 1024;
    /**
     * Node记录表
     */
    private Map<String, ListNode<String, V>> table = new ConcurrentHashMap<>();
    /**
     * 双向链表头部
     */
    private ListNode<String, V> head;
    /**
     * 双向链表尾部
     */
    private ListNode<String, V> tail;


    public LRUCache(int capacity) {
        this();
        this.capacity = capacity;
    }


    public LRUCache() {
        head = new ListNode<>();
        tail = new ListNode<>();
        head.next = tail;
        head.prev = null;
        tail.prev = head;
        tail.next = null;
    }


    public V get(String key) {

        ListNode<String, V> node = table.get(key);
        //如果Node不在表中,代表缓存中并没有
        if (node == null) {
            return null;
        }
        //如果存在,则需要移动Node节点到表头


        //截断链表,node.prev -> node  -> node.next ====> node.prev -> node.next
        //         node.prev <- node <- node.next  ====>  node.prev <- node.next
        node.prev.next = node.next;
        node.next.prev = node.prev;

        //移动节点到表头
        node.next = head.next;
        head.next.prev = node;
        node.prev = head;
        head.next = node;
        //存在缓存表
        table.put(key, node);
        return node.value;
    }


    public void put(String key, V value) {
        ListNode<String, V> node = table.get(key);
        //如果Node不在表中,代表缓存中并没有
        if (node == null) {
            if (table.size() == capacity) {
                //超过容量了 ,首先移除尾部的节点
                table.remove(tail.prev.key);
                tail.prev = tail.next;
                tail.next = null;
                tail = tail.prev;

            }
            node = new ListNode<>();
            node.key = key;
            node.value = value;
            table.put(key, node);
        }
        //如果存在,则需要移动Node节点到表头
        node.next = head.next;
        head.next.prev = node;
        node.prev = head;
        head.next = node;


    }

    /**
     * 双向链表内部类
     */
    public static class ListNode<K, V> {
        private K key;
        private V value;
        ListNode<K, V> prev;
        ListNode<K, V> next;

        public ListNode(K key, V value) {
            this.key = key;
            this.value = value;
        }


        public ListNode() {

        }
    }


    public static void main(String[] args) {
        LRUCache<ListNode> cache = new LRUCache<>(4);
        ListNode<String, Integer> node1 = new ListNode<>("key1", 1);
        ListNode<String, Integer> node2 = new ListNode<>("key2", 2);
        ListNode<String, Integer> node3 = new ListNode<>("key3", 3);
        ListNode<String, Integer> node4 = new ListNode<>("key4", 4);
        ListNode<String, Integer> node5 = new ListNode<>("key5", 5);
        cache.put("key1", node1);
        cache.put("key2", node2);
        cache.put("key3", node3);
        cache.put("key4", node4);
        cache.get("key2");
        cache.put("key5", node5);
        cache.get("key2");
    }
}

236二叉树最近公共祖先

package com.niukeoffer.a000LiKou.LK236二叉树最近公共祖先;

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x; }
}
public class Solution {
    private TreeNode ans;

    public Solution() {
        this.ans = null;
    }

    private boolean dfs(TreeNode root, TreeNode p, TreeNode q) {
        if (root == null) return false;
        boolean lson = dfs(root.left, p, q);
        boolean rson = dfs(root.right, p, q);
        if ((lson && rson) || ((root.val == p.val || root.val == q.val) && (lson || rson))) {
            ans = root;
        }
        return lson || rson || (root.val == p.val || root.val == q.val);
    }

    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        this.dfs(root, p, q);
        return this.ans;
    }

    public static void main(String[] args) {

    }

}

239滑动窗口的最大值

package com.niukeoffer.a000LiKou.LK239滑动窗口的最大值;

import java.util.ArrayDeque;

public class Solution {
    static ArrayDeque<Integer> deq = new ArrayDeque<Integer>();
    static int [] nums;

    public static void clean_deque(int i, int k) {
        // remove indexes of elements not from sliding window
        if (!deq.isEmpty() && deq.getFirst() == i - k)
            deq.removeFirst();

        // remove from deq indexes of all elements
        // which are smaller than current element nums[i]
        while (!deq.isEmpty() && nums[i] > nums[deq.getLast()])
            deq.removeLast();
    }

    public static int[] maxSlidingWindow(int[] array, int k) {
        int n = array.length;
        if (n * k == 0) return new int[0];
        if (k == 1) return array;

        // init deque and output
        nums = array;
        int max_idx = 0;
        for (int i = 0; i < k; i++) {
            clean_deque(i, k);
            deq.addLast(i);
            // compute max in nums[:k]
            if (nums[i] > nums[max_idx]) max_idx = i;
        }
        int [] output = new int[n - k + 1];
        output[0] = nums[max_idx];

        // build output
        for (int i  = k; i < n; i++) {
            clean_deque(i, k);
            deq.addLast(i);
            output[i - k + 1] = nums[deq.getFirst()];
        }
        return output;
    }

    public static void main(String[] args) {
        int [] nums = {1,3,-1,-3,5,3,6,7};
        int [] result = maxSlidingWindow(nums,3);
        for (int i = 0; i < result.length; i++) {
            System.out.print(result[i]+"  ");
        }
        System.out.println();
    }


}

329矩阵中最长递增路径

package com.niukeoffer.a000LiKou.LK329矩阵中最长递增路径;

class Solution {
    public static int[][] dirs = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
    public static int rows, columns;

    public static int longestIncreasingPath(int[][] matrix) {
        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
            return 0;
        }
        rows = matrix.length;
        columns = matrix[0].length;
        int[][] memo = new int[rows][columns];
        int ans = 0;
        for (int i = 0; i < rows; ++i) {
            for (int j = 0; j < columns; ++j) {
                ans = Math.max(ans, dfs(matrix, i, j, memo));
            }
        }
        return ans;
    }

    public static int dfs(int[][] matrix, int row, int column, int[][] memo) {
        if (memo[row][column] != 0) {
            return memo[row][column];
        }
        ++memo[row][column];
        for (int[] dir : dirs) {
            int newRow = row + dir[0], newColumn = column + dir[1];
            if (newRow >= 0 && newRow < rows && newColumn >= 0 && newColumn < columns && matrix[newRow][newColumn] > matrix[row][column]) {
                memo[row][column] = Math.max(memo[row][column], dfs(matrix, newRow, newColumn, memo) + 1);
            }
        }
        return memo[row][column];
    }

    public static void main(String[] args) {
        int [][] nums = {  {9,9,4},{6,6,8},{2,1,1}};
        System.out.println(longestIncreasingPath(nums));
    }
}


384打乱数组

package com.niukeoffer.a000LiKou.LK384打乱数组;

import java.util.Random;

public class Solution {
    private int[] array;
    private int[] original;

    Random rand = new Random();

    private int randRange(int min, int max) {
        return rand.nextInt(max - min) + min;
    }

    private void swapAt(int i, int j) {
        int temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }

    public Solution(int[] nums) {
        array = nums;
        original = nums.clone();
    }

    public int[] reset() {
        array = original;
        original = original.clone();
        return original;
    }

    public int[] shuffle() {
        for (int i = 0; i < array.length; i++) {
            swapAt(i, randRange(i, array.length));
        }
        return array;
    }


}

448找到数组中消失的数字

package com.niukeoffer.a000LiKou.LK448找到数组中消失的数字;

import java.util.LinkedList;
import java.util.List;

public class LK448 {
    public static List<Integer> findDisappearedNumbers(int[] nums) {

        // Iterate over each of the elements in the original array
        for (int i = 0; i < nums.length; i++) {

            int newIndex = Math.abs(nums[i]) - 1;

            if (nums[newIndex] > 0) {
                nums[newIndex] *= -1;
            }
        }
        // Response array that would contain the missing numbers
        List<Integer> result = new LinkedList<Integer>();

        for (int i = 1; i <= nums.length; i++) {

            if (nums[i - 1] > 0) {
                result.add(i);
            }
        }

        return result;
    }

    public static void main(String[] args) {
        int [] nums = {4,3,2,7,8,2,3,1};
        List<Integer> list = findDisappearedNumbers(nums);
        for (int i = 0; i < list.size(); i++) {
            System.out.print(list.get(i));
        }
        System.out.println();
    }

}

730统计不同回文子字符串

package com.niukeoffer.a000LiKou.LK730统计不同回文子字符串;

public class Solution {
    public static int countPalindromicSubsequences(String S) {
        int n = S.length();
        int mod = 1000000007;
        int[][][] dp = new int[4][n][n];

        for (int i = n-1; i >= 0; --i) {
            for (int j = i; j < n; ++j) {
                for (int k = 0; k < 4; ++k) {
                    char c = (char) ('a' + k);
                    if (j == i) {
                        if (S.charAt(i) == c) dp[k][i][j] = 1;
                        else dp[k][i][j] = 0;
                    } else { // j > i
                        if (S.charAt(i) != c) dp[k][i][j] = dp[k][i+1][j];
                        else if (S.charAt(j) != c) dp[k][i][j] = dp[k][i][j-1];
                        else { // S[i] == S[j] == c
                            if (j == i+1) dp[k][i][j] = 2; // "aa" : {"a", "aa"}
                            else { // length is > 2
                                dp[k][i][j] = 2;
                                for (int m = 0; m < 4; ++m) { // count each one within subwindows [i+1][j-1]
                                    dp[k][i][j] += dp[m][i+1][j-1];
                                    dp[k][i][j] %= mod;
                                }
                            }
                        }
                    }
                }
            }
        }

        int ans = 0;
        for (int k = 0; k < 4; ++k) {
            ans += dp[k][0][n-1];
            ans %= mod;
        }

        return ans;
    }


    public static void main(String[] args) {
        System.out.println(countPalindromicSubsequences("abcb"));
    }


}

940不同的子序列2

package com.niukeoffer.a000LiKou.LK940不同的子序列2;

import java.util.Arrays;

public class Solution {
    public static int distinctSubseqII(String S) {
        int MOD = 1_000_000_007;
        int N = S.length();
        int[] dp = new int[N+1];
        dp[0] = 1;

        int[] last = new int[26];
        Arrays.fill(last, -1);

        for (int i = 0; i < N; ++i) {
            int x = S.charAt(i) - 'a';
            dp[i+1] = dp[i] * 2 % MOD;
            if (last[x] >= 0)
                dp[i+1] -= dp[last[x]];
            dp[i+1] %= MOD;
            last[x] = i;
        }

        dp[N]--;
        if (dp[N] < 0) dp[N] += MOD;
        return dp[N];
    }

    public static void main(String[] args) {
        System.out.println(distinctSubseqII("abcdd"));
    }

}

1044最长重复子串

package com.niukeoffer.a000LiKou.LK1044最长重复子串;

import java.util.HashSet;

public class Main {
    public static int search(int L, int a, long modulus, int n, int[] nums) {
        // compute the hash of string S[:L]
        long h = 0;
        for (int i = 0; i < L; ++i) {
            h = (h * a + nums[i]) % modulus;
        }

        // already seen hashes of strings of length L
        HashSet<Long> seen = new HashSet();
        seen.add(h);
        // const value to be used often : a**L % modulus
        long aL = 1;
        for (int i = 1; i <= L; ++i) aL = (aL * a) % modulus;

        for (int start = 1; start < n - L + 1; ++start) {
            // compute rolling hash in O(1) time
            h = (h * a - nums[start - 1] * aL % modulus + modulus) % modulus;
            h = (h + nums[start + L - 1]) % modulus;
            if (seen.contains(h)) return start;
            seen.add(h);
        }
        return -1;
    }

    public static String longestDupSubstring(String S) {
        int n = S.length();
        // convert string to array of integers
        // to implement constant time slice
        int[] nums = new int[n];
        for (int i = 0; i < n; ++i) nums[i] = (int)S.charAt(i) - (int)'a';
        // base value for the rolling hash function
        int a = 26;
        // modulus value for the rolling hash function to avoid overflow
        long modulus = (long)Math.pow(2, 32);

        // binary search, L = repeating string length
        int left = 1, right = n;
        int L;
        while (left != right) {
            L = left + (right - left) / 2;
            if (search(L, a, modulus, n, nums) != -1) left = L + 1;
            else right = L;
        }

        int start = search(left - 1, a, modulus, n, nums);
        return start != -1 ? S.substring(start, start + left - 1) : "";
    }

    public static void main(String[] args) {
        System.out.println(longestDupSubstring("ananana"));
    }


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值