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