- 相同的树
public boolean isTreeSame(TreeNode root1, TreeNode root2) {
if (root1 == null && root2 == null) {
return true;
}
if (root1 == null || root2 == null) {
return false;
}
if (root1.val != root2.val ) {
return false;
}
return isTreeSame(root1.left, root2.left) && isTreeSame(root1.right, root2.right);
}
- 恢复二叉搜索树
public void recoverTree(TreeNode root) {
List<Integer> nums = new ArrayList<Integer>();
inorder(root, nums);
int[] values = findvalue(nums);
recover(root, values, 2);
}
public void inorder(TreeNode root, List<Integer> nums ) {
if (root == null) {
return;
}
inorder(root.left, nums);
nums.add(root.val);
inorder(root.right, nums);
}
public int[] findvalue(List<Integer> nums) {
int index1 = -1, index2 = -1;
for (int i = 0; i < nums.size() -1; i++) {
if (nums.get(i) > nums.get(i+1)) {
index2 = i + 1;
if (index1 == -1) {
index1 = i;
} else {
break;
}
}
}
return new int[] {nums.get(index1), nums.get(index2)};
}
public void recover(TreeNode root, int[] values, int count) {
int x = values[0], y = values[1];
if (root == null) {
return;
}
if (root.val == x || root.val ==y) {
root.val = root.val ==x ? y : x;
if(--count == 0) {
return;
}
}
recover(root.left, values, count);
recover(root.right, values, count);
}
102.验证二叉搜索树
public boolean isBTS(TreeNode root, int lower, int high) {
if (root == null) {
return true;
}
if (root.val >= high || root.val <= lower ) {
return false;
}
return isBTS(root.left,lower, root.val) && isBTS(root.right, root.val, high);
}
- 交错字符串
s1s2 = s3
f(i,j) = s2[j] == s3[i+j] && f(i, j-1)
s2s1 = s3
f(i,j) = s1[i] == s3[i+j] && f(i-1, j)
public boolean isInterleave(String s1, String s2, String s3) {
int n = s1.length();
int m = s2.length();
int s = s3.length();
if (n + m != s) {
return false;
}
boolean [][] f = new boolean[n+1][m+1];
f[0][0] = true;
for (int i = 0; i <= n; i++) {
for (int j = 0; j <=m; j++) {
int p = i + j -1;
if (i > 0) {
f[i][j] = f[i][j] || f[i -1][j] && s3.charAt(p) == s1.charAt(i-1);
}
if (j > 0) {
f[i][j] = f[i][j] || f[i][j-1] && s3.charAt(p) == s2.charAt(j-1);
}
}
}
return f[n][m];
}
100.不同的二叉搜索树
1~n,n长度
G[n]:表示长度为n的树的可能性
f(i,n)表示根节点为i,长度为n的树的可能性
G(n) = f(i,n) 之和i=0
f(i,n) = G(i-1) * G(n-i)
转换为:
G(n) = G(i-1) * G(n-i) 之和i =0
public int numTress(int n) {
int[] G = new int[n +1];
G[0] = 1;
G[1] = 1;
for (int i = 2; i <= n; i++) {
for (int j = 1; j <= i; j++) {
G[i] += G[j-1] * G[i -j];
}
}
return G[n];
}
- 不同的二叉搜索树II
i为根节点则:
左子树: 0 ~ i-1
右子树: i+1 ~ n
public List<TreeNode> generaTress(int start, int end) {
List<TreeNode> allTress = new LinkedList<TreeNode>();
if (start > end) {
allTress.add(null);
return allTress;
}
for (int i = start; i <= end; i++) {
List<TreeNode> leftTree = generaTress(start, i -1);
List<TreeNode> rightTree = generaTress(i +1, end);
for (TreeNode left : leftTree) {
for (TreeNode right: rightTree) {
TreeNode curr = new TreeNode();
curr.val = i;
curr.left = left;
curr.right = right;
allTress.add(curr);
}
}
}
return allTress;
}
- 树的中序遍历
中序遍历: 左子树--根--右子树
public List<Integer> treeMidum(TreeNode root) {
List<Integer> ans = new ArrayList<Integer>();
midumOrder(root, ans);
return ans;
}
public void midumOrder(TreeNode root, List<Integer> ans) {
if (root == null) {
return;
}
midumOrder(root.left, ans);
ans.add(root.val);
midumOrder(root.right, ans);
}
97.复原ip
给一个字符串,复原所有可能的ip
1. segment[4]
2. dfs
3. 如果是0, 则作为一个ip位
public List<String> restoreIp(String str) {
int SEG_COUNT = 4;
int[] segments = new int [SEG_COUNT];
List<String> ans = new ArrayList<String>();
dfs(str, 0, 0 ,segments, ans);
return ans;
}
public void dfs(String str, int segmentId, int segmentStart, int[] segments, List<String> ans ) {
if (segmentId == 4) {
if (segmentStart == str.length()) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 4; i++) {
sb.append(segments[i]);
if (i != 3) {
sb.append(".");
}
}
ans.add(sb.toString());
}
return;
}
if (segmentStart == str.length()) {
return;
}
if (str.charAt(segmentStart) == '0' ) {
segments[segmentId] = 0;
dfs(str, segmentId + 1, segmentStart + 1, segments, ans);
return;
}
int abbr = 0;
for (int segmentEnd = segmentStart; segmentEnd < str.length(); segmentEnd++) {
abbr = abbr * 10 + str.charAt(segmentEnd) - '0';
if (abbr > 0 && abbr < 256) {
segments[segmentId] = abbr;
dfs(str, segmentId + 1, segmentEnd +1, segments, ans);
} else {
break;
}
}
}
- 反转链表II
public LinkNode resver1(LinkNode head, int left, int right) {
LinkNode dumpHead = new LinkNode(0, null);
dumpHead.next = head;
LinkNode pre = dumpHead;
for (int i = 0; i < left -1;i++) {
pre = pre.next;
}
LinkNode curr = pre.next;
LinkNode next;
for (int i = 0; i < right - left; i++) {
next = curr.next;
curr.next = next.next;
next.next = pre.next;
pre.next = next;
}
return dumpHead.next;
}
- 解码方法
f[i] = f[i-1] + f[i -2]
public int numberEncoding(String str) {
int n = str.length();
int [] f = new int[n +1];
f[0] = 1;
for (int i = 1; i <=n; i++) {
if (str.charAt(i- 1) != '0') {
f[i] += f[i -1];
}
if (i > 1 && str.charAt(i -2) != '0' && ((str.charAt(i -2) - '0') * 10 + str.charAt(i-1) - '0') <= 26 ) {
f[i] += f[i -2];
}
}
return f[n];
}
94.子集ll
public List<List<Integer>> subSeque(int[] nums) {
List<List<Integer>> ans = new ArrayList<List<Integer>>();
List<Integer> t = new ArrayList<Integer>();
Arrays.sort(nums);
dfs(false, 0, nums, ans, t);
return ans;
}
public void dfs(boolean flag, int cur, int[] nums, List<List<Integer>> ans, List<Integer> t) {
if (cur == nums.length) {
ans.add(new ArrayList<Integer>(t));
return;
}
dfs(false, cur +1, nums, ans, t);
if (!flag && cur > 0 && nums[cur] == nums[cur -1]) {
return;
}
t.add(nums[cur]);
dfs(true, cur +1, nums, ans, t);
t.remove(t.size() -1);
}
- 格雷编码
2 = 4
00 = 0 00^10 = 10
01 = 1 01^10 = 11
10 = 2 10^11 = 01
11 = 3 11^11= 00
1^1 = 0
0^0 = 0
0^1 = 1
1^0 = 1
public List<Integer> graycode(int n) {
List<Integer> res = new ArrayList<Integer>();
for (int i = 0; i < (1 << n); i++ ) {
res.add( (i >> 1) ^ i );
}
return res;
}
- 合并两个有序数组
public void merger(int[] num1, int m, int[] num2, int n) {
int [] sort = new int[m +n];
int p1 = 0, p2 = 0;
int cur;
while(p1 < m || p2 < n) {
if (p1 == m) {
cur = num2[p2++];
} else if (p2 == n) {
cur = num1[p1++];
} else if (num1[p1] < num2[p2]) {
cur = num1[p1++];
} else {
cur = num2[p2++];
}
sort[p1 + p2 -1] = cur;
}
for (int i = 0; i < m +n ; i++) {
num1[i] = sort[i];
}
}
91.扰乱字符串
动态规划核心方程:
f(s1, s2) = (f[s1(0, i)][s2(0,i)] && f[s1(i, n -i)][s2(i, n-i)] ) || (f[s1(0,i)][s2(n -i,i)] && f[s1(i, n -1)][s2(0, n -i)])
res[l1][l2][i] && res[l1 + i][l2 +i][k -i]) || (res[l1][l2 + k -i][i] & res[l1 + i][l2][k-i])
k代表长度, i代表截断
public boolean isScramble(String s1, String s2) {
if (s1.length() != s2.length()) {
return false;
}
int n = s1.length();
// [s1的第几个字符][s2的第几个字符][长度]
boolean [][][] res = new boolean[n][n][n +1];
// 只有一个字符
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
res[i][j][1] = s1.charAt(i) == s2.charAt(j);
}
}
for (int k = 2; k <= n; k++ ) {
for (int l1 = 0; l1 <= n -k; l1++) {
for (int l2 =0; l2 <= n -k; l2++) {
for (int i = 1; i < k ; i++) {
if ( (res[l1][l2][i] && res[l1 + i][l2 +i][k -i]) || (res[l1][l2 + k -i][i] & res[l1 + i][l2][k-i]) ) {
res[l1][l2][k] = true;
}
}
}
}
}
return res[0][0][n];
}
90.分隔链表
public LinkNode splitLink(LinkNode head, int x) {
LinkNode smallHead = new LinkNode(0, null);
LinkNode small = smallHead;
LinkNode largeHead = new LinkNode(0, null);
LinkNode large = largeHead;
while(head != null) {
if (head.value < x) {
small.next = head;
small = small.next;
} else {
large.next = head;
large = large.next;
}
head = head.next;
}
large.next = null;
small.next = largeHead.next;
return smallHead.next;
}
- 柱状图中最大的矩形
找出某个元素的左右边界,左右边界大于这个元素的高度
利用栈来找
public int maxArea1(int [] nums) {
int n = nums.length;
int[] left = new int[n];
int[] right = new int[n];
Deque<Integer> stack = new ArrayDeque<Integer>();
for (int i = 0; i < n; i++) {
while(!stack.isEmpty() && nums[stack.peek()] >= nums[i] ) {
stack.poll();
}
left[i] = stack.isEmpty() ? -1 : stack.peek();
stack.push(i);
}
stack.clear();
for (int i = n -1; i > 0; i--) {
while(!stack.isEmpty() && nums[stack.peek()] >= nums[i] ) {
stack.poll();
}
right[i] = stack.isEmpty() ? n : stack.peek();
stack.push(i);
}
int ans = 0;
for (int i = 0; i < n; i++) {
ans = Math.max(ans, (right[i] - left[i] - 1) * nums[i]);
}
return ans;
}
- 删除排序链表中的重复元素
public LinkNode repeatSveOne(LinkNode head) {
if (head == null || head.next == null) {
return head;
}
LinkNode node = head;
while (node != null && node.next != null) {
int value = node.value;
if (value == node.next.value) {
while (node.next != null && value == node.next.value) {
node.next = node.next.next;
}
} else {
node = node.next;
}
}
return head;
}
- 删除排序链表中的重复元素ll
要注意设置一个哑元素 LinkNode node = new LinkNode(0, head);
public LinkNode deleteRepeat(LinkNode head) {
if (head == null || head.next == null) {
return head;
}
LinkNode node = new LinkNode(0, head);
LinkNode curr = node;
while (curr.next != null && curr.next.next != null) {
if (curr.next.value == curr.next.next.value) {
int value = curr.next.value;
while (curr.next != null && value == curr.next.value) {
curr.next = curr.next.next;
}
} else {
curr = curr.next;
}
}
return node.next;
}
- 搜索旋转排序数组ll
二分法
1.考虑数组为空
2.考虑数组只有一个
3.考虑旋转后刚好左右边界等于计算出来的Mid
4.mid等于target值
5. 考虑左边有序或者右边有序(总有一半是有序的)
public boolean equalsTarget(int[] nums, int target) {
int n = nums.length;
if (n == 0) {
return false;
}
if (n == 1) {
return nums[0] == target;
}
int l = 0;
int r = n -1;
while (l < r) {
int mid = (l + r)/2;
if (nums[mid] == target) {
return true;
}
if (nums[mid] == nums[l] && nums[mid] == nums[r]) {
r--;
l++;
} else if (nums[mid] >= nums[l]) {
if (nums[l] <= target && target < nums[mid]) {
r = mid -1;
} else {
l = mid + 1;
}
} else {
if (nums[r] < target && target < nums[n -1]) {
l = mid + 1;
} else {
r = mid -1;
}
}
}
return false;
}
- 番外 删除最小的K个数
public int[] mink(int [] nums, int k) {
int n = nums.length;
if (n < k) {
return nums;
}
Queue<Integer> queue = new PriorityQueue<Integer>(new Comparator<Integer>() {
@Override
public int compare(Integer num1, Integer num2) {
return num2 - num1;
}
});
for (int i = 0; i < k; i++) {
queue.offer(nums[i]);
}
for (int i = k; i < n ; i++) {
if (queue.peek() > nums[i]) {
queue.poll();
queue.offer(nums[i]);
}
}
int [] res = new int[k];
for (int i = 0; i < k; i++) {
res[i] = queue.poll();
}
return res;
}
- 删除有序数组中的重复项 ll
public int arrayLen(int [] nums) {
int len = nums.length;
if (len <= 2) {
return len;
}
int slow = 2, fast = 2;
while (fast < len) {
if (nums[slow -2] != nums[fast]) {
nums[slow] = nums[fast];
slow++;
}
fast++;
}
return slow;
}
83.单词搜索
public boolean searchWord(char[][] board, String word) {
int n = board.length;
int m = board[0].length;
boolean[][] vis = new boolean[n][m];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
boolean flag = check(board, word, i, j, 0, vis);
if (flag) {
return true;
}
}
}
return false;
}
public boolean check(char[][] board, String word, int i, int j, int k, boolean[][] vis) {
if (board[i][j] != word.charAt(k)) {
return false;
} else if (k == word.length() -1) {
return true;
}
vis[i][j] = true;
boolean result = false;
int[][] direction = { {0, -1}, {0, 1}, {1, 0}, {-1, 0} };
for (int[] dire: direction) {
int newi = i + dire[0];
int newj = j + dire[1];
if (newi >= 0 && newi < board.length && newj >= 0 && newj < board[0].length ) {
boolean flag = check(board, word, newi, newj, k +1, vis);
if (flag) {
result = true;
break;
}
}
}
vis[i][j] = false;
return result;
}
- 子集
回溯算法
public List<List<Integer>> allChild(int [] nums) {
List<List<Integer>> res = new ArrayList<List<Integer>>();
List<Integer> path = new ArrayList<Integer>();
dfs1(nums, 0, res, path);
return res;
}
public void dfs1(int[] nums, int start, List<List<Integer>> res, List<Integer> path) {
res.add(new ArrayList<Integer>(path));
for (int i = start; i < nums.length; i++) {
path.add(nums[i]);
dfs1(nums, i + 1, res, path);
path.remove(path.size() - 1 );
}
}
- 组合
回溯算法
public List<List<Integer>> zuhe(int n, int k) {
List<List<Integer>> res = new ArrayList<List<Integer>>();
List<Integer> path = new ArrayList<Integer>();
dfs(n, k, 1, path, res);
return res;
}
public void dfs(int n, int k, int start, List<Integer> path, List<List<Integer>> res) {
if (path.size() == k) {
res.add(new ArrayList<Integer>(path));
return;
}
for (int i = start; i <= n; i++) {
path.add(i);
dfs(n, k, i +1, path, res);
path.remove(path.size() - 1);
}
}
- 最小覆盖子串
滑动窗口
public String minContains(String s1, String t1) {
Map<Character, Integer> t1map = new HashMap<>();
Map<Character, Integer> s1map = new HashMap<>();
for (int i = 0; i < t1.length(); i++) {
t1map.put(t1.charAt(i), t1map.getOrDefault(t1.charAt(i) , 0) + 1);
}
int l = 0, r = -1;
int ansl = -1, ansr = -1;
int slen = s1.length();
int len = Integer.MAX_VALUE;
while(r < slen) {
++r;
if (r < slen && t1map.containsKey(s1.charAt(r))) {
s1map.put(s1.charAt(r), s1map.getOrDefault(s1.charAt(r), 0) + 1 );
}
while (check(t1map, s1map) && l <= r) {
if (r -l + 1 < len) {
len = r - l + 1;
ansl = l;
ansr = l + len;
}
if (s1map.containsKey(s1.charAt(l)) ) {
s1map.put(s1.charAt(l), s1map.getOrDefault(s1.charAt(l), 0 ) -1);
}
++l;
}
}
return ansl == -1 ? "" : s1.substring(ansl, ansr);
}
public boolean check(Map<Character, Integer> t1Map, Map<Character, Integer> s1Map) {
Iterator it = t1Map.entrySet().iterator();
while(it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
Character key = (Character) entry.getKey();
int value = (int)entry.getValue();
if (s1Map.getOrDefault(key, 0) < value) {
return false;
}
}
return true;
}
- 颜色分类
public void colorSort(int [] nums) {
int prt = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] == 0) {
int temp = nums[prt];
nums[prt] = nums[i];
nums[i] = temp;
prt++;
}
}
for (int i = prt; i < nums.length; i++) {
if (nums[i] == 1) {
int temp = nums[prt];
nums[prt] = nums[i];
nums[i] = temp;
prt++;
}
}
}
- 搜索二维矩阵
public boolean searchNums(int [][] nums, int target) {
int index = searchRow(nums, target);
if (index < 0) {
return false;
}
return searchNum(nums[index], target);
}
public int searchRow(int [][] nums, int target) {
int low = -1;
int high = nums.length - 1;
while(low < high) {
int mid = (high - low + 1) / 2 + low;
if (nums[mid][0] < target ) {
low = mid;
} else {
high = mid -1;
}
}
return low;
}
public boolean searchNum(int [] nums, int target) {
int low = 0;
int high = nums.length;
while(low <= high) {
int mid = (high - low ) / 2 + low;
if (nums[mid] == target) {
return true;
} else if (nums[mid] < target) {
low = mid + 1;
} else {
high = mid - 1;
}
}
return false;
}
- 矩阵置零
public int[][] setZeros(int [][] nums) {
int n = nums.length;
int m = nums[0].length;
boolean [] row = new boolean[n];
boolean [] col = new boolean[m];
for (int i = 0; i < n ; i++) {
for (int j = 0; j < m; j++) {
if (nums[i][j] == 0) {
row[i] = col[j] = true;
}
}
}
for (int i = 0; i < n ; i++) {
for (int j = 0; j < m; j++) {
if (row[i] || col[j]) {
nums[i][j] = 0;
}
}
}
return nums;
}
- 编辑距离
public int editDistant(String word1, String word2) {
int m = word1.length();
int n = word2.length();
int[][] dp = new int[m + 1][n + 1];
for (int i = 0; i < m +1 ; i++) {
dp[i][0] = i;
}
for (int j = 0; j < n+1; j++) {
dp[0][j] = j;
}
for (int i = 1; i < m +1; i++) {
for (int j = 1; j < n +1; j++) {
int left = dp[i -1][j] + 1;
int down = dp[i][j-1] + 1;
int left_down = dp[i-1][j-1];
if (word1.charAt(i-1) != word2.charAt(j-1)) {
left_down += 1;
}
dp[i][j] = Math.min(left, Math.min(down, left_down));
}
}
return dp[m][n];
}
- 简化路径
public String simplePath(String path) {
String [] nums = path.split("/");
Deque<String> stack = new ArrayDeque<String>();
for (String name : nums) {
if (name.equals("..")) {
if (!stack.isEmpty()) {
stack.pollLast();
}
} else if(name.length() > 0 && !name.equals(".")){
stack.offerLast(name);
}
}
StringBuilder sb = new StringBuilder();
if (stack.isEmpty()) {
sb.append("/");
} else {
while(!stack.isEmpty()) {
sb.append("/");
sb.append(stack.pollFirst());
}
}
return sb.toString();
}
- 爬楼梯
public int floor(int n) {
int q = 0;
int p = 0;
int r = 1;
for (int i = 1; i <= n; i++) {
q = p;
p = r;
r = q + p;
}
return r;
}
- x的平方根
public int mysqrt(int x) {
if (x == 0) {
return 0;
}
int ans = (int)Math.exp(0.5 * Math.log(x));
return (ans + 1) * (ans + 1) <= x ? ans + 1 : ans;
}
- 文本左右对齐
public List<String> full(String[] words, int maxWidth) {
int right = 0;
int n = words.length;
List<String> ans = new ArrayList<String>();
while(true) {
int left = right;
int numLen = 0;
while(right < n && numLen + words[right].length() + right - left <= maxWidth ) {
numLen = numLen + words[right++].length();
}
if (right == n) {
StringBuilder sb = join(words, left, right, " ");
sb.append(back(maxWidth - sb.length()));
ans.add(sb.toString());
return ans;
}
int numWord = right - left;
int numSpace = maxWidth - numLen;
if (numWord == 1) {
StringBuilder sb = new StringBuilder(words[left]);
sb.append(back(maxWidth - sb.length()));
ans.add(sb.toString());
continue;
}
int avgSpace = numSpace / (numWord -1);
int extraSapce = numSpace % (numWord - 1);
StringBuilder sb = join(words, left, left + extraSapce + 1, back(avgSpace + 1));
sb.append(back(avgSpace));
sb.append(join(words, left + extraSapce + 1, right, back(avgSpace)));
ans.add(sb.toString());
}
}
public StringBuilder join(String[] words, int left, int right, String step) {
StringBuilder sb = new StringBuilder(words[left]);
for(int i = left +1; i < right; i++ ) {
sb.append(step);
sb.append(words[i]);
}
return sb;
}
public String back(int n) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < n; i++) {
sb.append(" ");
}
return sb.toString();
}
- 二进制求和
public String binaryAdd(String s1, String s2) {
int len = Math.max(s1.length(), s2.length());
int res = 0;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < len; i++) {
res += i < s1.length() ? (s1.charAt(s1.length() - i - 1) - '0' ) : 0;
res += i < s2.length() ? (s2.charAt(s2.length() - i - 1) - '0' ) : 0;
sb.append( (char)(res % 2 + '0') );
res = res /2;
}
if (res > 0) {
sb.append('1');
}
sb.reverse();
return sb.toString();
}
- 加一
public int[] plusOne(int[] nums) {
int n = nums.length;
for (int i = n - 1; i >= 0; i--) {
if (nums[i] != 9) {
++nums[i];
for (int j = i+1; j < n; j++) {
nums[j] = 0;
}
return nums;
}
}
int [] res = new int[n +1];
res[0] = 1;
return res;
}
- 有效数字
enum State {
State_Init,
State_Singl,
State_Integer,
State_Point,
State_Point_with,
State_Factor,
State_Exp,
State_Exp_Sign,
State_Exp_Number,
State_End;
}
enum CharType {
Number,
Point,
Sign,
Exp,
Ilegal;
}
public boolean isNumber(String str){
int len = str.length();
Map<State, Map<CharType, State>> tranfer = new HashMap<State, Map<CharType, State>>();
Map<CharType, State> init = new HashMap<CharType, State>(){{
put(CharType.Number, State.State_Integer);
put(CharType.Point, State.State_Point_with);
put(CharType.Sign, State.State_Singl);
}};
tranfer.put(State.State_Init, init);
Map<CharType, State> sign = new HashMap<CharType, State>(){{
put(CharType.Number, State.State_Integer);
put(CharType.Point, State.State_Point_with);
}};
tranfer.put(State.State_Singl, sign);
Map<CharType, State> integer = new HashMap<CharType, State>(){{
put(CharType.Number, State.State_Integer);
put(CharType.Point, State.State_Point);
put(CharType.Exp, State.State_Exp);
}};
tranfer.put(State.State_Integer, integer);
Map<CharType, State> point = new HashMap<CharType, State>(){{
put(CharType.Exp, State.State_Exp);
put(CharType.Number, State.State_Factor);
}};
tranfer.put(State.State_Point, point);
Map<CharType, State> pointWith = new HashMap<CharType, State>(){{
put(CharType.Number, State.State_Factor);
}};
tranfer.put(State.State_Point_with, pointWith);
Map<CharType, State> factor = new HashMap<CharType, State>(){{
put(CharType.Number, State.State_Factor);
put(CharType.Exp, State.State_Exp);
}};
tranfer.put(State.State_Factor, factor);
Map<CharType, State> exp = new HashMap<CharType, State>(){{
put(CharType.Number, State.State_Exp_Number);
put(CharType.Sign, State.State_Exp_Sign);
}};
tranfer.put(State.State_Exp, exp);
Map<CharType, State> expSign = new HashMap<CharType, State>(){{
put(CharType.Number, State.State_Exp_Number);
}};
tranfer.put(State.State_Exp_Sign, expSign);
Map<CharType, State> expNumber = new HashMap<CharType, State>(){{
put(CharType.Number, State.State_Exp_Number);
}};
tranfer.put(State.State_Exp_Number, expNumber);
State state = State.State_Init;
for (int i = 0; i < len; i++) {
char ch = str.charAt(i);
CharType charType = toChartype(ch);
if (!tranfer.get(state).containsKey(charType)) {
return false;
}
state = tranfer.get(state).get(charType);
}
return state ==State.State_Integer || state == State.State_Factor || state == State.State_Exp_Number || state == State.State_Point || state == State.State_End;
}
public CharType toChartype(char ch) {
if (ch >= '0' && ch <= '9'){
return CharType.Number;
}
if (ch == '-' || ch == '+') {
return CharType.Sign;
}
if (ch == '.') {
return CharType.Point;
}
if (ch == 'e' || ch == 'E') {
return CharType.Exp;
}
return CharType.Ilegal;
}
- 最小路径和
public int minPathSum(int [][] nums) {
int n = nums.length;
int m = nums[0].length;
int[][] f = new int[n][m];
f[0][0] = nums[0][0];
for (int i = 1; i < n; i++) {
f[i][0] = f[i -1][0] + nums[i][0];
}
for (int j = 1; j < m; j++) {
f[0][j] = f[0][j -1] + nums[0][j];
}
for (int i = 1; i < n; i++) {
for (int j = 1; j < m; j++) {
f[i][j] = Math.min(f[i -1][j], f[i][j -1]) + nums[i][j];
}
}
return f[n -1][m -1];
}
- 不同路径II
public int pathSum1(int[][] nums) {
int n = nums.length;
int m = nums[0].length;
int [][] f = new int[n][m];
for (int i = 0; i < n; i++) {
if (nums[i][0] != 0) {
f[i][0] = 0;
break;
}
f[i][0] = 1;
}
for (int j = 0; j < m; j++) {
if (nums[0][j] != 0) {
f[0][j] = 0;
break;
}
f[0][j] = 1;
}
for (int i = 1; i < n; i++) {
for (int j = 1; j < m; j++) {
if (nums[i][j] != 1) {
f[i][j] = f[i -1][j] + f[i][j -1];
}
}
}
return f[n-1][m - 1];
}
- 不同路径
public int pathCnt(int n, int m) {
int[][] f = new int[n][m];
for (int i = 0; i < n; i++) {
f[i][0] = 1;
}
for (int j = 0; j < m; j++) {
f[0][j] = 1;
}
for (int i = 1; i < n; i++) {
for (int j = 1; j < m; j++) {
f[i][j] = f[i - 1][j] + f[i][j -1];
}
}
return f[n -1][m -1];
}
- 旋转链表
public LinkNode rotateRight(LinkNode head, int k) {
if (head == null || k == 0 ) {
return head;
}
LinkNode tail = head;
int len = 1;
while(tail.next != null) {
len++;
tail = tail.next;
}
if (len == k) {
return head;
}
tail.next = head;
int add = len - k % len;
while (add > 0) {
add--;
tail = tail.next;
}
LinkNode res = tail.next;
tail.next = null;
return res;
}
- 螺旋矩阵II
public int[][] martix(int n) {
int maxMaritx = n * n ;
int currentNum = 1;
int[][] res = new int[n][n];
int direIndex = 0;
int[][] direction = {{0, 1},{1, 0},{0, -1},{-1, 0}};
int row = 0;
int col = 0;
while(currentNum <= maxMaritx) {
res[row][col] = currentNum;
currentNum++;
int nextRow = row + direction[direIndex][0];
int nextCol = col + direction[direIndex][1];
if(nextRow < 0 || nextRow >= n || nextCol < 0 || nextCol >= n || res[nextRow][nextCol] != 0) {
direIndex = (direIndex +1 ) % 4;
}
row = row + direction[direIndex][0];
col = col + direction[direIndex][1];
}
return res;
}
63.最后一个单词的长度
public int leastSequeLen(String str) {
int len = str.length();
int index = len -1;
int leastLen = 0;
while(index >=0 && str.charAt(index) == ' ') {
index--;
}
while(index >= 0 && str.charAt(index) != ' ') {
index--;
leastLen++;
}
return leastLen;
}
- 插入区间
public int[][] merger1 (int[][] nums, int[] newNums) {
int left = newNums[0];
int right = newNums[1];
boolean flag = false;
List<int[]> merger = new ArrayList<int[]>();
for (int[] num : nums) {
if (num[0] > right) {
if (!flag) {
merger.add(new int[]{left, right});
flag = true;
}
merger.add(num);
} else if (num[1] < left ) {
merger.add(num);
} else {
left = Math.min(left, num[0]);
right = Math.max(right, num[1]);
}
}
if (!flag) {
merger.add(new int[]{left, right});
}
int[][] ans = new int[merger.size()][];
for (int i = 0; i < merger.size(); i++) {
ans[i] = merger.get(i);
}
return ans;
}
- 合并区间
public int[][] mergerArray(int[][] nums) {
int len = nums.length;
if (len == 0) {
return new int[0][2];
}
Arrays.sort(nums, new Comparator<int[]>() {
public int compare(int[] o1, int[] o2) {
return o1[0] - o2[0];
}
});
List<int[]> merger = new ArrayList<int[]>();
for (int[] num : nums) {
int left = num[0], right = num[1];
if (merger.size() == 0 || merger.get(merger.size()-1)[1] < left ) {
merger.add(num);
} else {
merger.get(merger.size() - 1)[1] = right;
}
}
return merger.toArray(new int[merger.size()][]);
}
- 跳跃游戏
public boolean skipGame(int[] nums) {
int len = nums.length;
int max = 0;
for (int i = 0; i < len; i++) {
if (max >= i) {
max = Math.max(max, i + nums[i]);
if (max >= len -1) {
return true;
}
}
}
return false;
}
- 螺旋矩阵
public List<Integer> luoxuan(int[][] martix) {
List<Integer> res = new ArrayList<Integer>();
int rows = martix.length;
int cols = martix[0].length;
int left = 0, right = cols -1;
int top = 0, bottom = rows -1;
while(left <= right && top <= bottom) {
for (int i = left; i <= right; i++) {
res.add(martix[top][i]);
}
for (int i = top + 1; i <= bottom; i++) {
res.add(martix[i][right]);
}
if (left < right && top < bottom) {
for (int i = right -1 ; i >= left; i-- ) {
res.add(martix[bottom][i]);
}
for (int i = bottom -1; i > top; i--) {
res.add(martix[i][left]);
}
}
left++;
right--;
top++;
bottom--;
}
return res;
}
- 最大子数组和
public int maxChildSeque(int[] nums) {
int max = nums[0];
int pre = 0;
for (int x : nums) {
pre = Math.max(x, pre + x);
max = Math.max(max, pre);
}
return max;
}
- N皇后II
public int queues1(int n) {
int[] queue = new int[n];
Arrays.fill(queue, -1);
Set<Integer> col1 = new HashSet<Integer>();
Set<Integer> da1 = new HashSet<Integer>();
Set<Integer> da2 = new HashSet<Integer>();
int i = back1(queue, n, 0, col1, da1, da2);
return i;
}
public int back1(int[] queue, int n, int row, Set<Integer> col1, Set<Integer> da1, Set<Integer> da2) {
if (n == row) {
return 1;
}
int count = 0;
for (int i = 0; i < n ; i++) {
if (col1.contains(i)) {
continue;
}
int da11 = row - i;
if (da1.contains(da11)) {
continue;
}
int da22 = row + i;
if (da2.contains(da22)) {
continue;
}
col1.add(i);
da1.add(da11);
da2.add(da22);
count = count + back1(queue, n , row+1, col1, da1, da2);
col1.remove(i);
da1.remove(da11);
da2.remove(da22);
}
return count;
}
- N皇后
public List<List<String>> queues(int n) {
List<List<String>> res = new ArrayList<List<String>>();
int[] queue = new int[n];
Arrays.fill(queue, -1);
Set<Integer> col1 = new HashSet<Integer>();
Set<Integer> da1 = new HashSet<Integer>();
Set<Integer> da2 = new HashSet<Integer>();
back(queue, n, 0, col1, da1, da2, res);
return res;
}
public void back(int[] queue, int n, int row, Set<Integer> col1, Set<Integer> da1, Set<Integer> da2, List<List<String>> res ) {
if (n == row) {
List<String> str = board(queue, n);
res.add(str);
return;
}
for (int i = 0; i < n ; i++) {
if (col1.contains(i)) {
continue;
}
int da11 = row - i;
if (da1.contains(da11)) {
continue;
}
int da22 = row + i;
if (da2.contains(da22)) {
continue;
}
queue[row] = i;
col1.add(i);
da1.add(da11);
da2.add(da22);
back(queue, n , row+1, col1, da1, da2, res);
queue[row] = -1;
col1.remove(i);
da1.remove(da11);
da2.remove(da22);
}
}
public List<String> board(int[] queue, int n) {
List<String> res = new ArrayList<String>();
for (int i = 0; i < n; i++) {
char [] chars = new char[n];
Arrays.fill(chars, '.');
chars[queue[i]] = 'Q';
res.add(new String(chars));
}
return res;
}
55.实现pow(x,n)
public double pow(double x, int n) {
long N = n;
return N >= 0 ? mul(x, N) : 1.0/mul(x,-N);
}
public double mul(double x, long n) {
double ans = 1.0;
double double_x = x;
while(n > 0) {
if (n % 2 == 1) {
ans = ans * double_x;
}
double_x = double_x * double_x;
n = n /2;
}
return ans;
}
- 字母异位词分组
public List<List<String>> yiwei(String[] nums) {
Map<String, List<String>> map = new HashMap<String, List<String>>();
for (String num : nums) {
char [] chars = num.toCharArray();
Arrays.sort(chars);
String s1 = new String(chars);
List<String> list = map.get(s1);
if (list == null) {
list = new ArrayList<String>();
}
list.add(num);
map.put(s1, list);
}
return new ArrayList<List<String>>(map.values());
}
53.旋转图像
核心: nums[col][n - row -1] = nums[row][col]
public void xuanzhuan(int[][] nums) {
int n = nums.length;
for (int row = 0; row < n/2; row++) {
for (int col = 0; col < (n+1)/2; col++) {
int temp = nums[row][col];
nums[row][col] = nums[n - 1 - col][row];
nums[n - 1 - col][row] = nums[n - row -1][n -1 -col];
nums[n - row -1][n -1 -col] = nums[col][n - row - 1];
nums[col][n - row - 1] = temp;
}
}
}
- 全排列2
数组有重复元素
boolean[] bis;
public List<List<Integer>> pailie2(int[] nums) {
List<List<Integer>> res = new ArrayList<List<Integer>>();
List<Integer> ans = new ArrayList<Integer>();
bis = new boolean[nums.length];
Arrays.sort(nums);
back2(nums, res, ans, 0);
return res;
}
public void back2(int[] nums, List<List<Integer>> res, List<Integer> ans, int n) {
if (n == nums.length) {
res.add(new ArrayList<Integer>(ans));
return;
}
for (int i = 0; i < nums.length; i++) {
if (bis[i] || (i > 0 && nums[i] == nums[i -1] && !bis[i-1]) ) {
continue;
}
ans.add(nums[i]);
bis[i] = true;
back2(nums, res, ans, n +1);
bis[i] = false;
ans.remove(n);
}
}
- 全排列
输入数组不重复
public List<List<Integer>> pailie(int [] nums) {
List<List<Integer>> res = new ArrayList<List<Integer>>();
List<Integer> output = new ArrayList<Integer>();
for (int num : nums) {
output.add(num);
}
int len = nums.length;
back(len, res, output, 0);
return res;
}
public void back(int len, List<List<Integer>> res, List<Integer> output, int first) {
if (first == len) {
res.add(new ArrayList<Integer>(output));
}
for (int i = first; i < len; i++) {
Collections.swap(output, i, first);
back(len, res, output, first +1);
Collections.swap(output, i , first);
}
}
public void printListList(List<List<Integer>> res) {
for (List<Integer> list : res) {
for (Integer num : list) {
System.out.printf(num + ",");
}
System.out.println("");
}
}
- 跳跃游戏Ⅱ
public int skip(int[] nums) {
int len = nums.length;
int step = 0;
int end = 0;
int maxPosition = 0;
for (int i = 0; i < len -1; i++) {
maxPosition = Math.max(maxPosition, i + nums[i]);
if (i == end) {
end = maxPosition;
step++;
}
}
return step;
}
- 字符串相乘
public String mul(String num1, String num2) {
if (num1.equals("0") || num2.equals("0") ) {
return "0";
}
String res = "";
for (int i = num1.length() -1; i >= 0; i-- ) {
StringBuilder temp = new StringBuilder();
for (int j = 0; j < num1.length() - i - 1; j++) {
temp.append("0");
}
int carry = 0;
int n1 = num1.charAt(i) - '0';
for (int j = num2.length() -1; j >= 0 || carry != 0; j-- ) {
int n2 = j < 0 ? 0 : num2.charAt(j) - '0';
int value = (n1 * n2 + carry) %10;
temp.append(value);
carry = (n1 * n2 + carry) /10;
}
res = addString(res, temp.reverse().toString());
}
return res.toString();
}
public String addString(String num1, String num2) {
StringBuilder res = new StringBuilder();
int carry = 0;
for (int i = num1.length() -1, j = num2.length() -1; i >= 0 || j >= 0 || carry != 0 ; i--, j-- ) {
int n1 = i < 0 ? 0 : num1.charAt(i) - '0';
int n2 = j < 0 ? 0 : num2.charAt(j) - '0';
int sum = (n1 + n2 + carry) % 10;
res.append(sum);
carry = (n1 + n2 + carry) /10;
}
return res.reverse().toString();
}
- 接雨水
public int yushui(int[] nums) {
int left = 0;
int right = nums.length -1;
int left_max = 0;
int right_max = 0;
int ans = 0;
while(left < right){
if (nums[left] < nums[right]) {
if (nums[left] > left_max) {
left_max = nums[left];
} else {
ans = ans + left_max - nums[left];
}
left++;
} else {
if (nums[right] > right_max) {
right_max = nums[right];
} else {
ans = ans + right_max - nums[right];
}
right--;
}
}
return ans;
}
- 缺失的第一个正数
public int minValue(int [] nums) {
int len = nums.length;
for (int i = 0; i < len; i++) {
while(nums[i] > 0 && nums[i] <= len && nums[nums[i] - 1] != nums[i]) {
swapArray(nums, i, nums[i] -1);
}
}
for (int i = 0; i < len; i++) {
if (nums[i] != i + 1 ) {
return i +1;
}
}
return len +1;
}
public void swapArray(int [] nums, int index, int index1) {
int temp = nums[index];
nums[index] = nums[index1];
nums[index1] = temp;
}
- 组合总数二
public List<List<Integer>> shulie(int [] nums, int target) {
List<List<Integer>> ans = new ArrayList<List<Integer>>();
List<Integer> combine = new ArrayList<Integer>();
Arrays.sort(nums);
dfs(nums, target, 0, combine, ans);
return ans;
}
public void dfs(int[] nums, int target, int start, List<Integer> combine, List<List<Integer>> ans) {
if (target < 0) {
return;
}
if(target == 0) {
ans.add(new ArrayList(combine));
return;
}
for (int i = start; i < nums.length; i++) {
if (i > start && nums[i] == nums[i -1]) {
continue;
}
combine.add(nums[i]);
dfs(nums, target - nums[i], i + 1 , combine, ans);
combine.remove(combine.size() - 1);
}
}
- 组合总和
public List<List<Integer>> shulie(int [] nums, int target) {
List<List<Integer>> ans = new ArrayList<List<Integer>>();
List<Integer> combine = new ArrayList<Integer>();
dfs(nums, target, 0, combine, ans);
return ans;
}
public void dfs(int[] nums, int target, int start, List<Integer> combine, List<List<Integer>> ans) {
if (target < 0) {
return;
}
if(target == 0) {
ans.add(new ArrayList(combine));
return;
}
for (int i = start; i < nums.length; i++) {
combine.add(nums[i]);
dfs(nums, target - nums[i], i, combine, ans);
combine.remove(combine.size() - 1);
}
}
44.前观数列
public String countAndSay(int n) {
String str = "1";
for (int i = 2; i <= n; i++) {
StringBuilder sb = new StringBuilder();
int pos = 0;
int start = 0;
while(pos < str.length()) {
while(pos < str.length() && str.charAt(pos) == str.charAt(start)) {
pos++;
}
sb.append(Integer.toString(pos - start)).append(str.charAt(start));
start = pos;
}
str = sb.toString();
}
return str;
}
- 解数独
public class sudu{
boolean [][] col = new boolean[9][9];
boolean [][] row = new boolean[9][9];
boolean [][][] box = new boolean[3][3][9];
boolean valid = false;
List<int[]> spaces = new ArrayList<int[]>();
public void solvesudo(char[][] board) {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
char c = board[i][j];
if (c == '.') {
spaces.add(new int[]{i, j});
} else {
int digt = c - '0' - 1;
col[i][digt] = row[j][digt] = box[i][j][digt] = true;
}
}
}
dfs(board, 0);
}
public void dfs(char[][] board, int pos) {
if (spaces.size() == pos) {
valid = true;
return;
}
int[] space = spaces.get(pos);
int i = space[0];
int j = space[1];
for (int digt = 0; digt < 9 && !valid; digt++) {
col[i][digt] = row[j][digt] = box[i/3][j/3][digt] = true;
board[i][j] = (char)(digt - '0' + 1);
dfs(board, pos + 1);
col[i][digt] = row[j][digt] = box[i/3][j/3][digt] = false;
}
}
}
- 有效数独
public boolean judgesudu(char[][] borad) {
int [][] col = new int [9][9];
int [][] row = new int[9][9];
int[][][] box = new int[3][3][9];
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
char c = borad[i][j];
if (c != '.') {
int index = c - '0' -1;
col[i][index]++;
row[j][index]++;
box[i\3][j\3][index]++;
if (col[i][index] > 1 || row[j][index] > 1 || box[i\3][j\3][index] > 1 ) {
return false;
}
}
}
}
return true;
}
- 搜索插入位置
public int searchInsert(int[] nums, int target) {
int l = 0;
int r = nums.length -1;
int ans = nums.length;
while(l <= r) {
int mid = (l + r ) / 2;
if (nums[mid] >= target) {
r = mid -1;
ans = mid;
} else {
l = mid +1;
}
}
return ans;
}
- 在排序数组中查找元素的第一个和最后一个位置
public int[] findIndex(int[] nums, int target) {
int left = searchIndex(nums, target, true);
int right = searchIndex(nums, target, false) -1;
if (left <= right && right < nums.length && nums[left] == target && nums[right] == target) {
return new int[] {left, right};
}
return new int[] {-1, -1};
}
public int searchIndex(int[] nums, int target, boolean lower) {
int len = nums.length;
int l = 0;
int r = len -1;
int ans = 0;
while(l <= r) {
int mid = (l + r) / 2;
if (nums[mid] > target || (lower && nums[mid] >= target ) ) {
r = mid - 1;
ans = mid;
} else {
l = mid + 1;
}
}
return ans;
}
39.搜索旋转排序数组
public int findTarget(int [] nums, int target) {
int len = nums.length;
if (len == 0) {
return -1;
}
if (len ==1) {
return nums[0] == target ? 0 : -1;
}
int l = 0;
int r = len -1;
while(l <= r) {
int mid = (r + l )/2;
if (nums[mid] == target) {
return mid;
}
if (nums[0] <= nums[mid]) {
if (nums[0] <= target && target < nums[mid] ) {
r = mid - 1;
} else {
l = mid +1;
}
} else {
if (nums[mid] < target && target <= nums[len -1] ) {
l = mid + 1;
} else {
r = mid -1;
}
}
}
return -1;
}
- 下一个排列
public void nextPailie(int[] nums) {
int len = nums.length;
int j = len -2;
while(j >= 0 && nums[j] >= nums[j +1]) {
j--;
}
if (j >= 0) {
int i = len - 1;
while(i >= 0 && nums[j] > nums[i] ) {
i--;
}
swap(nums, i, j);
}
resver(nums, j +1);
}
public void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
public void resver(int[] nums, int start) {
int left = start;
int right = nums.length - 1;
while(left < right) {
swap(nums, left, right);
left++;
right--;
}
}
- 最长的有效括号
public int maxlong(String str) {
int len = str.length();
int [] dp = new int[len];
int maxAns = 0;
for (int i = 1 ; i <len; i++ ) {
if (str.charAt(i) == ')' ) {
if (str.charAt(i -1 ) == '(') {
dp[i] = (i -2 > 0 ? dp[i -2 ] : 0) + 2;
} else if (i - dp[i -1] - 2 > 0 && str.charAt(i - dp[i-1] -1 ) == '(' ) {
dp[i] = dp[i -1] + dp[i - dp[i -1] -2] + 2;
}
}
maxAns = Math.max(maxAns, dp[i]);
}
return maxAns;
}
36.两数相除
public int div(int dividend, int divisor) {
if (divisor == 0) {
return 0;
}
if (dividend == Integer.MAX_VALUE ){
if (divisor == 1) {
return Integer.MAX_VALUE;
}
if (divisor == -1) {
return Integer.MIN_VALUE;
}
}
if (dividend == Integer.MIN_VALUE ){
if (divisor == 1) {
return Integer.MIN_VALUE;
}
if (divisor == -1) {
return Integer.MAX_VALUE;
}
}
if (divisor == Integer.MAX_VALUE ) {
if (dividend == Integer.MAX_VALUE) {
return 1;
}else if (dividend == Integer.MIN_VALUE) {
return -1;
} else {
return 0;
}
}
if (divisor == Integer.MIN_VALUE ) {
if (dividend == Integer.MAX_VALUE) {
return -1;
}else if (dividend == Integer.MIN_VALUE) {
return 1;
} else {
return 0;
}
}
boolean flag = false;
if (dividend > 0) {
dividend = -dividend;
flag = !flag;
}
if (divisor > 0) {
divisor = -divisor;
flag = !flag;
}
List<Integer> ansList = new ArrayList<Integer>();
ansList.add(divisor);
int index = 0;
while(ansList.get(index) > dividend - ansList.get(index) ) {
ansList.add(ansList.get(index) + ansList.get(index));
index++;
}
int ans = 0;
for (int i = ansList.size() - 1; i >= 0; i-- ) {
if (ansList.get(i) >= dividend ) {
ans += 1 << i;
dividend -= ansList.get(i);
}
}
return flag ? -ans : ans;
}
35.实现strStr()
暴力法: O(m*n)
public int strStr(String s, String pp) {
int n = s.length();
int m = pp.length();
for (int i = 0; i + m < n; i++) {
boolean flag = true;
for (int j = 0; j < m; j++) {
if (s.charAt(i+j) != pp.charAt(j) ) {
flag = false;
break;
}
}
if (flag) {
return i;
}
}
return -1;
}
KMP算法: O(m+n)
public int strStr(String s, String p) {
int n = s.length();
int m = p.length();
if (m == 0) {
return 0;
}
int [] pi = new int[m];
for (int i= 1, j = 0; i < m ; i++) {
while(j > 0 && p.charAt(i) != p.charAt(j) ) {
j = pi[j-1];
}
if (p.charAt(i) == p.charAt(j)) {
j++;
}
pi[i] = j;
}
for (int i = 0, j = 0; i < n; i++) {
while(j > 0 && s.charAt(i) != p.charAt(j) ) {
j = pi[i];
}
if (s.charAt(i) == p.charAt(j)) {
j++;
}
if (j == m) {
return i - m +1;
}
}
return -1;
}
- 移除元素
public int removeVal(int[] nums, int val) {
int len = nums.length;
if (len == 0) {
return 0;
}
int left = 0;
for(int right = 0; right < len; right++) {
if (nums[right] != val) {
nums[left] = nums[right];
left++;
}
}
return left;
}
- 删除有序数组中的重复项
public int removeRepeat(int[] nums) {
int len = nums.length;
if (len == 0) {
return 0;
}
int slow = 1;
int fast = 1;
for (int i = 1; i < len; i++) {
if (nums[fast] != nums[fast-1]) {
nums[slow] = nums[fast];
slow++;
}
fast++;
}
return slow;
}
- K个一组反转链表
public LinkNode revserGroup(LinkNode head, int k) {
if (head == null || head.next == null) {
return head;
}
LinkNode tail = head;
for (int i = 0 ; i < k; i++ ) {
if (tail == null) {
return head;
}
tail = tail.next;
}
LinkNode newHead = resver(head, tail);
head.next = revserGroup(tail ,k);
return newHead;
}
public LinkNode resver(LinkNode head, LinkNode tail) {
LinkNode next = null;
LinkNode pre = null;
while(head != tail) {
next = head.next;
head.next = pre;
pre = head;
head = next;
}
return pre;
}
31.两两交换链表中的节点
public LinkNode swap(LinkNode node) {
if (node == null || node.next == null) {
return node;
}
LinkNode newHead = node.next;
node.next = swap(node.next.next);
newHead.next = node;
return newHead;
}
- 合并K个升序链表
public LinkNode merger(LinkNode l1, LinkNode l2) {
if (l1 == null) {
return l2;
} else if (l2 == null) {
return l1;
} else if (l1.value < l2.value) {
l1.next = merger(l1.next, l2);
return l1;
} else {
l2.next = merger(l1, l2.next);
return l2;
}
}
public LinkNode merges (LinkNode[] list) {
LinkNode node = null;
for (LinkNode node1 : list) {
node = merger(node, node1);
}
return node;
}
- 括号生成
ArrayList[] cache = new ArrayList[100];
public List<String> generate(int n) {
if (cache[n] != null ) {
return cache[n];
}
ArrayList<String> ans = new ArrayList<String>();
if (n == 0) {
ans.add("");
} else {
for (int i = 0; i < n; i++) {
for (String left : generate(i)) {
for (String right : generate(n - i - 1)) {
ans.add('(' + left + ')' + right);
}
}
}
}
cache[n] = ans;
return ans;
}
- 合并两个有序链表
public LinkNode mergeTwo(LinkNode l1, LinkNode l2) {
if (l1 == null) {
return l2;
} else if (l2 == null) {
return l1;
} else if (l1.value < l2.value) {
l1.next = mergeTwo(l1.next, l2);
return l1;
} else {
l2.next = mergeTwo(l1, l2.next);
return l2;
}
}
27.有效的括号
public boolean judgeStr(String s) {
int len = s.length();
if (len % 2 == 1) {
return false;
}
Map<Character, Character> map = new HashMap<Character, Character>();
map.put(')', '(');
map.put(']', '[');
map.put('}', '{');
LinkedList<Character> link = new LinkedList<Character>();
for (int i = 0; i < len; i++) {
char ch = s.charAt(i);
if (map.containsKey(ch)) {
if (link.isEmpty() || map.get(ch) != link.getLast() ) {
return false;
}
link.removeLast();
} else {
link.add(ch);
}
}
return link.isEmpty();
}
- 删除列表的倒数第N个节点
public LinkNode removeN(LinkNode head, int n) {
if (head == null || n <= 0) {
return null;
}
int len = getLength(head);
LinkNode node = new LinkNode();
node.next = head;
node.value = 0;
for (int i = 1; i < lenght - n + 1; i++) {
node = node.next;
}
node.next = node.next.next;
return head;
}
public int getLength(LinkNode head) {
int length = 0;
while(head != null) {
head = head.next;
length++;
}
return length;
}
- 电话号码的字母组合
public List<String> get(String s) {
List<String> res = new ArrayList<String>();
if (s == null) {
return res;
}
Map<Character, String> map = new HashMap<Character, String>();
map.put('2', "abc");
map.put('3', "def");
map.put('4', "ghi");
map.put('5', "jkl");
map.put('6', "mno");
map.put('7', "pqrs");
map.put('8', "tuv");
map.put('9', "wxyz");
find(s, res, map, 0, new StringBuilder());
return res;
}
public void find(String s, List<String> res, Map map, int index , StringBuilder dig) {
if (index == s.length()) {
res.add(dig.toString());
} else {
char ch = s.charAt(index);
String letter = (String)map.get(ch);
for (int i = 0 ; i < letter.length(); i++ ) {
char c = letter.charAt(i);
dig.append(c);
find(s, res, map, index+1, dig);
dig.deleteCharAt(index);
}
}
}
24.最接近的三数之和
public int threeNum(int[] nums, int target){
int n = nums.length;
Arrays.sort(nums);
int ans = nums[0] + nums[1] + nums[2];
for (int i =1; i < n; i++) {
int start = i + 1;
int end = n -1;
while(start < end) {
int sum = nums[i] + nums[start] + nums[end];
if (Math.abs(sum - target) < Math.abs(ans - target)) {
ans = sum;
}
if (sum < target) {
start++;
} else if (sum > target) {
end--;
} else {
return ans;
}
}
}
return ans;
}
23.三数只和
public List<List<Integer>> threeNum(int[] nums) {
int n = nums.length;
Arrays.sort(nums);
List<List<Integer>> list = new ArrayList<List<Integer>>();
// a b c
for (int first = 0; first < n; first++) {
if (first > 0 && nums[first] == nums[first - 1]) {
continue;
}
int three = n -1;
for (int scecond = first + 1; scecond < n; scecond++) {
if (scecond > first +1 && nums[scecond] == nums[scecond -1]) {
continue;
}
while(scecond < three && nums[scecond] + nums[three] + nums[first] != 0 ) {
three--;
}
if(scecond == three) {
break;
}
if (nums[first] + nums[scecond] + nums[three] == 0) {
List<Integer> res = new ArrayList<Integer>();
res.add(nums[first]);
res.add(nums[scecond]);
res.add(nums[three]);
list.add(res);
}
}
}
return list;
}
- 最长公共前缀
public String maxCommonSub(String[] arrays) {
if (arrays == null) {
return "";
}
String ans = arrays[0];
String s1 = arrays[0];
for (int i = 1; i < arrays.length; i++) {
int j = 0;
for (; j < ans.length() && j < arrays[i].length(); j++ ) {
if (s1.charAt(j) != arrays[i].charAt(j) ) {
break;
}
}
ans = ans.substring(0, j);
}
return ans;
}
21 罗马数字转整数
public int luomaToInt(String s1) {
Map<Character, Integer> map = new HashMap<Character, Integer>();
map.put('I', 1);
map.put('V', 5);
map.put('X', 10);
map.put('L', 50);
map.put('C', 100);
map.put('D', 500);
map.put('M', 1000);
int n = s1.length();
int ans = 0;
for (int i = 0; i < n; i++) {
int value = map.get(s1.charAt(i));
if (i < n-1 && value < map.get(s1.charAt(i+1)) ) {
ans = ans - value;
} else {
ans = ans + value;
}
}
return ans;
}
- 整数转罗马数字
publuic String luoma(int num) {
int[] arrays = {1000, 900, 500, 400, 100, 90, 50, 40, 10 ,9, 5, 4, 1};
String[] array1 = { "M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};
StringBuilder sb = new StringBuilder();
for (int i = 0; i < arrays.length; i++ ) {
int value = arrays[i];
while(num >= value ) {
num = num - value;
sb.append(array1[i]);
}
if (num == 0) {
break;
}
}
return sb.toString();
}
19.盛水最多的容器
public int maxArea(int[] arrays) {
if (arrays == null) {
return 0;
}
int l = 0;
int r = arrays.length -1;
int ans = 0;
while(l < r) {
int area = Math.min(arrays[l], arrays[r]) * (r-l);
ans = Math.max(ans, area);
if (arrays[l] <= arrays[r]) {
l++;
} else {
r--;
}
}
return ans;
}
18.正则表达式
public boolean isMatch(String s, String p){
int m = s.length();
int n = p.length();
boolean[][] dp = new boolean [m+1][n+1];
dp[0][0] = true;
for (int i = 0; i<= m; ++i) {
for (int j =1; j <=n; ++j) {
if (p.charAt(j-1) == '*') {
dp[i][j] = dp[i][j-2];
if (match(s,p,i,j-1)) {
dp[i][j] = dp[i][j] || dp[i-1][j];
}
} else {
if (match(s,p, i, j)) {
dp[i][j] = dp[i-1][j-1];
}
}
}
}
return dp[m][n];
}
public boolean match(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 boolean judege(int x) {
if (x < 0 || (x % 10 == 0 && x != 0)) {
return false;
}
int num = 0;
while(x > num) {
num = num * 10 + x % 10;
x = x /10;
}
return x == num || num/10 == x;
}
16.字符串转整数
public int myAtoi(String s1) {
if (s1 == null || s1.length() == 0) {
return 0;
}
int index = 0;
char[] chars = s1.toCharArray();
int len = s1.length();
while(index < len && chars[index] == ' ') {
index++;
}
if (index >= len) {
return 0;
}
int sign = 1;
if (chars[index] == '+') {
index++;
} else if (chars[index] == '-') {
sign = -1;
index++;
}
int res = 0;
while(index < len) {
char ch = chars[index];
if (ch < '0' || ch > '9' ) {
break;
}
int tmp = ch - '0';
if (res > Integer.MAX_VALUE/10 || (res == Integer.MAX_VALUE / 10 && ch > Integer.MAX_VALUE % 10 ) ) {
return 0;
}
if (res < Integer.MIN_VALUE/10 || (res == Integer.MIN_VALUE / 10 && ch > -(Integer.MIN_VALUE % 10) ) ) {
return 0;
}
res = res * 10 + sign * tmp;
index++;
}
return res;
}
15 整数反转
public int reserver(int x) {
int res = 0;
while(x != 0) {
int temp = x % 10;
if (res > Integer.MAX_VALUE /10 || res < Integer.MIN_VALUE /10) {
return 0;
}
res = res * 10 + temp;
x = x/10;
}
return res;
}
14 z型变换
public String reserver(String s1, int rowNum) {
if (rowNum < 2) {
return s1;
}
StringBuilder[] sbs = new StringBuilder[rowNum];
int flag = -1;
int i = 0;
char[] chars = s1.toCharArray();
for (char ch: chars) {
sbs[i].append(ch);
if (i ==0 || i+1 == rowNum ) {
flag = -flag;
}
i = i + flag;
}
StringBuilder sb = new StringBuilder();
for(StringBuilder s : sbs ) {
sb.append(s);
}
return sb.toString();
}
13 最长回文子串
public String lonngestPalindrome(String s1) {
int len = s1.length();
if (len < 2 ) {
return s1;
}
char[] chars = s1.toCharAray();
boolean [][] dp = new boolean[len][len];
for (int i = 0; i < len; i++) {
dp[i][i] = true;
}
int begin = 1;
int maxLen = 0;
for (int L = 2; L <= len; L++ ) {
for (int i = 0; i < len; i++) {
int j = L + i - 1;
if (j >= len) {
break;
}
if (chars[i] == chars[j]) {
if (j-i < 3) {
dp[i][j] = true;
} else {
dp[i][j] = dp[i+ 1] [j -1];
}
} else {
dp[i][j] = false;
}
if (dp[i][j] & j - i +1 > maxLen ) {
begin = i;
maxLen = j -i +1;
}
}
return s1.subString(begin, begin+maxLen);
}
}
- 输出两个有序数组的中位数
public double mid(int[] num1, int start1, int end1, int[] num2, int start2, int end2, int k) {
int len1 = end1 - start1 +1;
int len2 = end2 - start2 +1;
if (len1 == 0) {
return num2[start2 + k -1 ];
} else if(len2 == 0) {
return num1[start1 + k -1];
}
if (k == 1) {
return Math.min(num1[start1], num2[start2]);
}
int i = start1 + Math.min(len1, k/2) - 1;
int j = start2 + Math.min(len2, k/2) -1;
if (num1[i] < num2[j]) {
return mid(num1, i +1 , end1, num2, start2, end2, k - (i - start1 +1) );
} else {
return mid(num1, start1, end1, num2, j +1 , end2, k - (j - start1 +1) );
}
}
public double find(int[] num1, int[] num2) {
int len1 = num1.length;
int len2 = num2.length;
return (mid(num1, 0 , len1 -1, num2, 0, len2 -1, (len1+ len2 +1)/2 )
+
mid(num1, 0 , len1 -1, num2, 0, len2 -1, (len1+ len2 +2)/2 )
) * 0.5;
}
- 求无序数组的中位数
public int mid(int[] arrays, int length, int k) {
if (arrays == null) {
return 0;
}
int smallCnt = 0;
int equalCnt = 0;
int bigCnt = 0;
int[] smallArrays = new int[length];
int[] equalArrays = new int[length];
int[] bigArrays = new int[length];
int base = arrays[0];
for (int i = 0; i < length; i++) {
if (base > arrays[i]) {
smallArrays[smallCnt] = arrays[i];
smallCnt++;
} else if (base == arrays[i]) {
equalArrays[equalCnt] = arrays[i];
equalCnt++;
} else {
bigArrays[bigCnt] = arrays[i];
bigCnt++;
}
}
if (k <= smallCnt) {
return mid(smallArrays, smallCnt, k);
} else if (k > smallCnt + equalCnt) {
return mid(bigArrays, bigCnt, k - smallCnt - equalCnt);
} else {
return base;
}
}
public int mid(int [] arrays) {
int midValue = 0;
if (arrays.length % 2 == 0 ) {
int count1 = mid(arrays, arrays.length, arrays.length/2);
int count2 = mid(arrays, arrays.length, arrays.length/2 + 1);
midValue = (count1 + count2) / 2;
} else {
midValue = mid(arrays, arrays.length, (arrays.length +1)/2);
}
return midValue;
}
- 无重复字符的最长子串
滑动窗口
public int maxSubStr(String s1) {
if (s1 == null) {
return 0;
}
HashSet<Charraset> set = new HashSet();
int left = 0;
int right = 0;
int max = 0;
for (; right < s1.length(); right++) {
Charraset ch = s1.charAt(right);
while(set.contains(ch)) {
set.remove(s1.charAt(left));
left++;
}
set.add(ch);
max = Math.max(max, right -left +1);
}
return max;
}
9.两数相加
public LinkNode add(LinkNode l1, LinkNode l2) {
LinkNode head = null;
LinkNode tail = null;
int carry = 0;
while(l1 != null || l2 != null) {
int l1 = l1 != null ? l1.value : 0;
int l2 = l2 != null ? l2.value : 0;
int sum = l1 + l2 + carry;
if (head == null) {
head = new LinkNode(sum % 10);
tail = head;
} else {
tail.next = new LinkNode(sum % 10);
tail = tail.next;
}
if (l1 != null) {
l1 = l1.next;
}
if (l2 != null) {
l2 = l2.next;
}
carry = sum / 10;
}
if (carry > 0) {
tail.next = new LinkNode(carry);
}
return head;
}
8.两数之和
public int[] find(int[] arrays, int target) {
if (arrays == null) {
return null;
}
Map<Integer, Integer> map = new HashMap();
for (int i = 0; i < arrays.length; i++) {
if (map.containkey(target - arrays[i])) {
return new int[]{map.get(target - arrays[i]), i };
}
map.put(arrays[i], i);
}
return new int[0];
}
7.从尾到头输出链表
public void print(LinkNode node) {
if (node == null) {
return;
}
if (node.next != null) {
print(node.next);
}
System.out.print(node.value)
}
6.输入二维数组,找出是否指定值存在
public boolean find(int[][] arrays, int rows, int cols, int target) {
if (arrays == null || rows < 0 || cols < 0) {
}
int row = 0;
int col = cols -1;
while (row < rows && col > 0 ) {
if (arrays[row][col] == target) {
return true;
} else if(arrays[row][col] > target) {
col--;
} else {
row ++;
}
}
return false;
}
5.判断数组是否是树的后序遍历
public boolean judge(int[] arrays, int start, int end) {
if (arrays == null || start < 0 || end < 0) {
return false;
}
int root = arrays[end];
int i = 0;
for (; i < end; i++) {
if (arrays[i] > root ){
break;
}
}
int j = i;
for (; j < end; j++) {
if (arrays[j] < root ) {
return false;
}
}
boolean left = true;
if (i > start) {
left = judge(arrays, start, i);
}
boolean right = true;
if (i < end) {
right = judge(arrays, i, end -1);
}
return left && right;
}
4.输出二叉树的后序遍历
public void print(TreeNode root) {
if (root == null) {
return;
}
if (root != null) {
print(root.left);
print(root.right);
}
system.out.print(root.value);
}
3.找出数组中重复的数字
public int find(int[] arrays) {
if (arrays == null) {
return -1;
}
HashSet<Integer> set = new HashSet();
for (int i = 0; i < arrays.length; i++) {
int number = arrays[i];
if (set.contains(number)) {
return number;
}
set.add(number);
}
return -1;
}
2.快速排序
public void quickSort(int [] nums, int left ,int right) {
if (nums == null || left > right) {
return;
}
int base = nums[left];
int i = left;
int j = right;
while (i < j) {
while(nums[j] > base && i < j) {
j--;
}
while(nums[i] < base && i < j) {
i++;
}
int temp = nums[j];
nums[j] = nums[i];
nums[i] = temp;
}
quickSort(nums, left , j -1);
quickSort(nums, j+1, right);
}
1.一个整形数组中除了两个数字之外,其他都出现了两次,请找出两个只出现一次的数字
//只有一个不重复的 找出一个重复的
public Integer find(int[] arrays) {
if (arrays == null) {
return null;
}
int number = arrays[0];
for (int i = 1; i < arrays.length; i++) {
number = number ^ arrays[i];
}
return number;
}
public int[] find(int[] arrays) {
Integer[] result = new Integer[2];
if (arrays == null) {
return result;
}
int orx = arrays[0];
for (int i = 1; i < arrays.length; i++) {
orx = orx ^ arrays[i];
}
int index = findIndex(orx);
result[0] = 0;
result[1] = 0;
for (int num : arrays) {
if (isBit(num, index)) {
result[0] = result[0] ^ num;
} else {
result[1] = result[1] ^ num;
}
}
}
boolean isBit(int num, int index) {
return (num >>> index) & 1 == 1;
}
int findIndex(orx) {
int index = 0;
while(orx & 1 == 0 && index < 32) {
index++;
orx = orx >>> 1;
}
return index;
}