(。_ 。) ✎(╮(๑•́ ₃•̀๑)╭)
说明:
(含剑指Offer补充题目)
(部分题提供多种解法)
百度网盘——剑指Offer——PDF
/**
* No.2 单例模式
*/
private static volatile Offer singleton;
/**
* 构造函数私有化
*/
private Offer() {
}
/**
* 双重检查
*
* @return
*/
public static Offer getSingleton() {
if (singleton == null) {
synchronized (Offer.class) {
if (singleton == null) {
singleton = new Offer();
}
}
}
return singleton;
}
/**
* No.3 任意重复的数
*
* @param nums
* @return
*/
public static int getRepeatedNum(int[] nums) {
for (int i = 0; i < nums.length; i++) {
while (nums[i] != i) {
int temp = nums[i];
if (nums[temp] == temp) {
return temp;
} else {
nums[i] = nums[temp];
nums[temp] = temp;
}
}
}
return -1;
}
/**
* 不改变数组找出重复的数
* n+1 的数组 1~n 的数
* 空间 o(N)
*
* @param nums
* @return
*/
public static int getRepeatedN(int[] nums) {
int[] arr = new int[nums.length];
for (int i = 0; i < nums.length; i++) {
arr[nums[i]]++;
if (arr[nums[i]] > 1) {
return nums[i];
}
}
return -1;
}
/**
* 解法二
* 空间 o(1)
*
* @param nums
* @return
*/
public static int getRepeatedM(int[] nums) {
int len = nums.length;
int start = 0;
int end = len - 1;
while (end >= start) {
int mid = (end - start) >> 1 + start;
int count = countRange(nums, len, start, mid);
if (start == end) {
if (count > 1) {
return start;
} else {
break;
}
}
if (count > (mid - start + 1)) {
end = mid;
} else {
start = mid + 1;
}
}
return -1;
}
private static int countRange(int[] nums, int len, int start, int end) {
int count = 0;
for (int i = 0; i < len; i++) {
if (nums[i] >= start && nums[i] <= end) {
count++;
}
}
return count;
}
/**
* No.4 二维数组中的查找
* 行/列 有序
* 矩阵问题考虑四个顶点
*
* @param matrix
* @param target
* @return
*/
public static boolean isExist(int[][] matrix, int target) {
int row = matrix.length;
int col = matrix[0].length;
if (target < matrix[0][0] || target > matrix[row][col])
return false;
int i = 0, j = col;
while (j >= 0 && i <= row) {
if (matrix[i][j] == target)
return true;
else if (matrix[i][j] < target)
i++;
else
j--;
}
return false;
}
/**
* No.5 替换空格
* API
* @param s
* @return
*/
public static String replaceSpaceI(String s){
return s.replace(" ","%20");
}
/**
* 解法二
* 双指针
* @param s
* @return
*/
public static String replaceSpaceII(String s) {
char[] origin = s.toCharArray();
int lenO = s.length();
int countSpace = 0;
// 统计空格数
for (int i = 0; i < lenO; i++) {
if (origin[i] == ' ') {
countSpace++;
}
}
char[] current = new char[lenO + 2 * countSpace];
System.arraycopy(origin, 0, current, 0, lenO);
int lenC = current.length;
lenC = lenC - 1;
lenO = lenO - 1;
while (lenC > lenO) {
if (current[lenO] != ' ') {
current[lenC--] = current[lenO--];
} else {
current[lenC--] = '0';
current[lenC--] = '2';
current[lenC--] = '%';
lenO--;
}
}
return String.valueOf(current);
}
/**
* 补充:两排序数组合并
* 从后往前!!!
* @param A1
* @param A2
* @return
*/
public static int[] concatOrderArray(int[] A1, int[] A2) {
int index = A1.length - 1;
int j = A2.length - 1;
int i = index - j -1;
while (j >= 0) {
if (A2[j] >= A1[i]) {
A1[index--] = A2[j--];
} else {
A1[index--] = A1[i--];
}
}
return A1;
}
/**
* N0.6 从尾到头打印链表
*
* @param head
*/
public static void printLinkedListI(ListNode head) {
Stack s = new Stack<>();
ListNode node = head;
while (node != null) {
s.push(node);
node = node.next;
}
while (!s.isEmpty()) {
System.out.println(s.pop().val);
}
}
/**
* 解法二 递归
* @param head
*/
public static void printLinkedListII(ListNode head) {
if (head == null)
return;
printLinkedListII(head.next);
System.out.println(head.val);
}
/**
* No.7 重建二叉树
*
* @param preOrder
* @param inOrder
* @return
*/
public static TreeNode buildTree(int[] preOrder, int[] inOrder) {
return buildTree(preOrder, 0, preOrder.length - 1, inOrder, 0, inOrder.length - 1);
}
private static TreeNode buildTree(int[] preOrder, int startP, int endP, int[] inOrder, int startI, int endI) {
if (startP > endP) {
return null;
}
int rootVal = preOrder[startP];
TreeNode root = new TreeNode(rootVal);
int index = 0;
while (inOrder[index] != rootVal) {
index++;
}
root.left = buildTree(preOrder, startP + 1, startP + index - startI, inOrder, startI, index - 1);
root.right = buildTree(preOrder, startP + index - startI + 1, endP, inOrder, index + 1, endI);
return root;
}
/**
* No.8 二叉树的下一个节点
* 中序遍历
*
* @param root
* @param target
* @return
*/
public static TreeNode nextNodeI(TreeNode root, TreeNode target) {
ArrayList list = new ArrayList<>();
inOrder(root, list);
for (int i = 0; i < list.size(); i++) {
TreeNode current = list.get(i);
if (current.val == target.val && i + 1 < list.size()) {
return list.get(i + 1);
}
}
return null;
}
private static void inOrder(TreeNode root, ArrayList list) {
if (root == null)
return;
inOrder(root.left, list);
list.add(root);
inOrder(root.right, list);
}
/**
* No.8 二叉树的下一个节点
* 中序遍历
* @param target
* @return
*/
public static TreeNode nextNodeII(TreeNode target) {
if (target == null)
return null;
TreeNode next = null;
// 右子树存在,取右子树的最左节点
if (target.right != null) {
TreeNode right = target.right;
while (right.left != null) {
right = right.left;
}
next = right;
}
// 右子树不存在,取其父节点路径中拥有左子节点的节点
else {
if (target.parent != null) {
TreeNode current = target;
TreeNode parent = target.parent;
while (parent != null && current == parent.right){
current = parent;
parent = parent.parent;
}
next = parent;
}
}
return next;
}
/**
* No.9 用两个栈实现队列
*
* @param
*/
class QueueQ {
private Stack s1 = new Stack<>();
private Stack s2 = new Stack<>();
;
public void appendTail(T ele) {
s1.push(ele);
}
public T deleteHead() {
if (!s2.isEmpty()) {
return s2.pop();
}
while (!s1.isEmpty()) {
s2.push(s1.pop());
}
return s2.pop();
}
}
/**
* 用两个队列实现栈
*
* @param
*/
class StackS {
private Queue q1 = new LinkedList<>();
private Queue q2 = new LinkedList<>();
public void push(T ele) {
if (q1.isEmpty() && q2.isEmpty()) {
q1.offer(ele);
}
else if (q1.isEmpty()) {
q2.offer(ele);
}
else{
q1.offer(ele);
}
}
public T pop() {
if (q1.isEmpty()) {
while (q2.size() > 1) {
q1.offer(q2.poll());
}
return q2.poll();
}
if(q2.isEmpty()){
while (q1.size() > 1) {
q2.offer(q1.poll());
}
return q1.poll();
}
return null;
}
}
/**
* No.10 斐波那契数列
* 递归
*
* @param n
* @return
*/
public static int fibonacciI(int n) {
if (n == 0) {
return 0;
}
if (n == 1) {
return 1;
}
return fibonacciI(n - 1) + fibonacciI(n - 2);
}
/**
* 解法二 动态规划
*
* @param n
* @return
*/
public static int fibonacciII(int n) {
int[] fibonacci = new int[n + 1];
fibonacci[0] = 0;
fibonacci[1] = 1;
for (int i = 2; i <= n; i++) {
fibonacci[i] = fibonacci[i - 1] + fibonacci[i - 2];
}
return fibonacci[n];
}
/**
* No.11 旋转(有序)数组中最小的数字
* 二分法 + 特例!!!
* @param num
* @return
*/
public static int minOfRotateArray(int[] num) {
int p1 = 0;
int p2 = num.length - 1;
int mid = p1;
while (num[p1] >= num[p2]) {
if (p2 - p1 == 1) {
mid = p2;
break;
}
mid = (p2 - p1) >> 1 + p1;
// 三个未知的数均相等
if (num[p1] == num[mid] && num[mid] == num[p2]) {
return getMinOfArray(num);
}
else {
if (num[mid] > num[p1]) {
p1 = mid;
}
else {
p2 = mid;
}
}
}
return num[mid];
}
private static int getMinOfArray(int[] num) {
int min = Integer.MAX_VALUE;
for (int n : num) {
min = n < min ? n : min;
}
return min;
}
/**
* No.12 矩阵中的路径
* 回溯法
* @param matrix
* @param s
* @return
*/
private static boolean hasPath(char[][] matrix, String s) {
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
boolean[][] visited = new boolean[matrix.length][matrix[0].length];
// matrix[i][j] 起点
if (hasPathCore(matrix, i, j, s, visited)) {
return true;
}
}
}
return false;
}
private static boolean hasPathCore(char[][] matrix, int startI, int startJ, String s, boolean[][] visited) {
if(s.length()==0){
return true;
}
if (startI >= 0 && startI < matrix.length && startJ >= 0 && startJ < matrix[0].length) {
if (matrix[startI][startJ] == s.charAt(0) && !visited[startI][startJ]) {
visited[startI][startJ] = true;
if(hasPathCore(matrix,startI-1,startJ,s.substring(1),visited)||
hasPathCore(matrix,startI+1,startJ,s.substring(1),visited)||
hasPathCore(matrix,startI,startJ-1,s.substring(1),visited)||
hasPathCore(matrix,startI,startJ+1,s.substring(1),visited)){
return true;
}
}
}
return false;
}
/**
* No.13 机器人的运动范围
* @param matrix
* @param num
* @return
*/
private static int movingCount(int[][] matrix, int num) {
boolean[][] visited = new boolean[matrix.length][matrix[0].length];
return getCount(matrix,0,0,num,visited);
}
private static int getCount(int[][] matrix, int i, int j, int num, boolean[][] visited) {
int count = 0;
if (i >= 0 && i < matrix.length && j >= 0 && j < matrix[0].length && !visited[i][j]) {
if (checkRule(i, j, num)) {
visited[i][j] = true;
count = 1 + getCount(matrix, i - 1, j, num, visited)
+ getCount(matrix, i + 1, j, num, visited)
+ getCount(matrix, i, j - 1, num, visited)
+ getCount(matrix, i, j + 1, num, visited);
}
}
return count;
}
// 规则检查
private static boolean checkRule(int i, int j, int num) {
if (getSum(i) + getSum(j) <= num) {
return true;
}
return false;
}
// 各位数求和
private static int getSum(int n) {
int result = 0;
while (n > 0) {
result += n % 10;
n /= 10;
}
return result;
}
/**
* No.14 剪绳子
* f(n)=max(f(i)*f(n-i)) 01)
return false;
}
return count==1;
}
/**
* 二进制下m到n变化的位数
* @param m
* @param n
* @return
*/
public static int mTon(int m,int n){
int num = m^n;
int count = 0;
while(n!=0){
n = n&(n-1);
count++;
}
return count;
}
/**
* Excel列号编码
* @param s
* @return
*/
public static int coloum(String s){
int[] table = new int[256];
for(int i='A';i<='Z';i++){
table[i] = i-'A'+1;
}
char[] t = s.toCharArray();
int num = 0;
for(char c:t){
int n = table[c];
num = num*26+n;
}
return num;
}
/**
* No.16 数值的正数次方
* @param m
* @param n
* @return
*/
public static double power1(double m,int n){
double res = 1;
int abs = n;
if(m==0)
return 0;
if(n<0)
abs = -n;
for(int i=1;i<=abs;i++){
res*=m;
}
return n<0?(1.0/res):res;
}
/**
* 递归
* @param m
* @param n
* @return
*/
public static double power2(double m,int n){
if(n==0)
return 1;
if(m==0)
return 0;
double res = power2(m,Math.abs(n)>>1);
res*=res;
if((n&1)==1)
res*=m;
return n<0?(1.0/res):res;
}
/**
* No.17 打印从1到最大的n位数
* @param n
*/
public static void printToN(int n){
char[] number = new char[n];
for (int i = 0; i < number.length; i++) {
number[i] = '0';
}
while(!increment(number)){
printNumber(number);
}
}
public static boolean increment(char[] number){
//溢出
boolean isOver = false;
//进位
int carry = 0;
for(int i=number.length-1;i>=0;i--){
int num = number[i] - '0' +carry;
if(i==number.length-1)
num++;
if(num>=10){
if(i==0)
isOver = true;
else{
number[i] = '0';
carry = 1;
}
}
else{
number[i] = (char) (num+48);
break;
}
}
return isOver;
}
public static void printNumber(char[] number){
boolean isBeginning0 = true;
for (int i = 0; i < number.length; i++) {
//从第一个不为0的开始打印到末尾
if(isBeginning0&&number[i]!='0')
isBeginning0 = false;
if(!isBeginning0)
System.out.print(number[i]);
}
System.out.println();
}
/**
* No.18 删除指定节点
* @param head
* @param node
* @return
*/
public static ListNode deleteNode(ListNode head,ListNode node){
if(node.next!=null){
node.val = node.next.val;
node.next = node.next.next;
}
else{
if(node==head){
return null;
}
else{
ListNode current = head;
while(current.next!=node){
current = current.next;
}
current.next = null;
}
}
return head;
}
/**
* 删除重复节点(有序链表)
* @param head
* @return
*/
public static ListNode deleteDuplicateNode(ListNode head){
ListNode preHead = new ListNode(-1);
preHead.next = head;
ListNode pre = preHead;
ListNode cur = preHead;
while(cur!=null&&cur.next!=null){
if(cur.val!=cur.next.val) {
cur = cur.next;
}
else{
while(pre.next.val!=cur.val)
pre = pre.next;
while(cur.next!=null&&cur.val==cur.next.val)
cur = cur.next;
cur = cur.next;
pre.next =cur;
}
}
return preHead.next;
}
/**
* 删除重复节点(有序链表)
* 别人写得好系列 ╮( •́ω•̀ )╭
* @param pHead
* @return
*/
public ListNode deleteDuplication(ListNode pHead) {
// 只有0个或1个结点,则返回
if (pHead == null || pHead.next == null) {
return pHead;
}
// 当前结点是重复结点
if (pHead.val == pHead.next.val) {
ListNode pNode = pHead.next;
// 跳过值与当前结点相同的全部结点,找到第一个与当前结点不同的结点
while (pNode != null && pNode.val == pHead.val) {
pNode = pNode.next;
}
// 从第一个与当前结点不同的结点开始递归
return deleteDuplication(pNode);
}
// 当前结点不是重复结点
else {
// 保留当前结点,从下一个结点开始递归
pHead.next = deleteDuplication(pHead.next);
return pHead;
}
}
/**
* No.19 正则表达式匹配
* @param str
* @param pattern
* @return
*/
public static boolean match(char[] str, char[] pattern)
{
//return new String(str).matches(new String(pattern));
if(str==null||pattern==null)
return false;
int strIndex=0;
int patternIndex=0;
return matchCore(str,strIndex,pattern,patternIndex);
}
private static boolean matchCore(char[] str, int strIndex,char[] pattern,int patternIndex){
//有效性检验:str到尾,pattern到尾,匹配成功
if(strIndex==str.length&&patternIndex==pattern.length)
return true;
//pattern先到尾,匹配失败
if(strIndex!=str.length&&patternIndex==pattern.length)
return false;
//模式第2个是*
if(patternIndex+11)
return false;
if(i==0||i==str.length-1||str[i-1]<48||str[i-1]>57)
return false;
point++;
continue;
}
if(str[i]=='.'){
point++;
if(point>1)
return false;
continue;
}
if(str[i]<48||str[i]>57)
return false;
}
return true;
}
/**
* No.21 调整数组顺序使奇数在前偶数在后
* @param array
*/
public static void reOrderArray1(int [] array) {
int i = 0,j = array.length-1;
while (ii&&array[j]%2==0)
j--;
while(i=k)
second=second.next;
first=first.next;
}
return i set = new HashSet<>();
while(pHead!=null){
if(set.contains(pHead))
return pHead;
set.add(pHead);
pHead = pHead.next;
}
return null;
}
/**
* 解法二
* 快慢指针
* @param pHead
* @return
*/
public static ListNode EntryNodeOfLoop2(ListNode pHead)
{
ListNode slow = pHead;
ListNode fast = pHead;
while(fast!=null){
slow = slow.next;
fast = fast.next;
if(fast!=null)
fast = fast.next;
if(slow==fast)
break;
}
if(fast==null)
return null;
while(slow!=pHead){
slow = slow.next;
pHead = pHead.next;
}
return pHead;
}
/**
* No.24 反转链表
* @param head
* @return
*/
public ListNode ReverseList(ListNode head) {
ListNode preHead = new ListNode(-1);
ListNode node = null;
while (head!=null){
node = head;
head = head.next;
node.next=null;
node.next = preHead.next;
preHead.next = node;
}
return preHead.next;
}
/**
* No.25 合并有序链表
* @param list1
* @param list2
* @return
*/
public static ListNode Merge1(ListNode list1,ListNode list2) {
ListNode preHead = new ListNode(-1);
ListNode current = preHead;
while(list1!=null&&list2!=null){
if(list1.valtopY)
System.out.print(matrix[i][j--]);
while(i>topX)
System.out.print(matrix[i--][j]);
topX++;
topY++;
botX--;
botY--;
}
}
/**
* No.30 包含min函数的栈
*/
private class Solution {
Stack stack = new Stack<>();
Stack min = new Stack<>();
public void push(int node) {
stack.push(node);
if(min.isEmpty())
min.push(node);
else{
if(node stack = new Stack<>();
for (int i = 0,j=0; i < popOrder.length; i++) {
while (stack.isEmpty()||stack.peek()!=popOrder[i]){
if(j==inOrder.length)
break;
stack.push(inOrder[j]);
j++;
}
if(stack.peek()!=popOrder[i])
break;
stack.pop();
if(stack.isEmpty()&&i==popOrder.length-1)
res=true;
}
return res;
}
/**
* No.32 从上到下打印二叉树(不分行)
* @param root
*/
public static void printBylayer1(TreeNode root){
Queue queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()){
TreeNode node = queue.poll();
System.out.println(node.val);
if(node.left!=null)
queue.offer(node.left);
if(node.right!=null)
queue.offer(node.right);
}
}
/**
* 分行打印
* @param root
*/
public static void printBylayer2(TreeNode root){
Queue queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()){
int num = queue.size();
while(num-->0) {
TreeNode node = queue.poll();
System.out.print(node.val);
if (node.left != null)
queue.offer(node.left);
if (node.right != null)
queue.offer(node.right);
}
System.out.println();
}
}
/**
* 之字形打印
* @param root
*/
public static void printBylayer3(TreeNode root){
Stack[] stacks = new Stack[2];
stacks[0] = new Stack();
stacks[1] = new Stack();
int current = 0;
int next = 1;
stacks[current].push(root);
while (!stacks[0].isEmpty()||!stacks[1].isEmpty()){
TreeNode node = (TreeNode) stacks[current].pop();
System.out.print(node.val);
if(current==0){
if (node.left != null)
stacks[next].push(node.left);
if (node.right != null)
stacks[next].push(node.right);
}
else{
if (node.right != null)
stacks[next].push(node.right);
if (node.left != null)
stacks[next].push(node.left);
}
if(stacks[current].isEmpty()){
current=1-current;
next=1-next;
System.out.println();
}
}
}
/**
* No.33 二叉搜索树后序遍历序列
* @param num
* @param start
* @param end
* @return
*/
public static boolean verifyBSTPost(int[] num,int start,int end){
int root = num[end];
int i=start;
//分割点
for(;iroot)
break;
}
int j=i;
for(;jstart)
left=verifyBSTPost(num,start,i-1);
boolean right=true;
if(istart;i--)
if(num[i]start;j--)
if(num[j]>root)
return false;
boolean left=true;
if(i>start)
left=verifyBSTPre(num,start+1,i);
boolean right=true;
if(i> res = new ArrayList<>();
public ArrayList> FindPath(TreeNode root,int target){
ArrayList lt = new ArrayList<>();
findPath(root,target,lt);
return res;
}
private void findPath(TreeNode root,int target,ArrayList lt){
if(root==null)
return;
lt.add(root.val);
target-=root.val;
if(target==0&&root.left==null&&root.right==null)
res.add(new ArrayList<>(lt));
findPath(root.left,target,lt);
findPath(root.right,target,lt);
lt.remove(lt.size()-1);
}
/**
* No.35 复杂链表复制
* @param head
* @return
*/
public static RandomListNode cloneList(RandomListNode head){
if(head==null)
return null;
//复制next节点
RandomListNode cur = head;
while(cur!=null){
RandomListNode node = new RandomListNode(cur.label);
node.next=cur.next;
cur.next=node;
cur=node.next;
}
//复制pre节点
cur = head;
while(cur!=null){
if(cur.random!=null) {
RandomListNode next = cur.next;
next.random=cur.random.next;
}
cur=cur.next.next;
}
//新链表
cur = head;
RandomListNode newHead = head.next;
while(cur.next!=null){
RandomListNode next = cur.next;
cur.next=next.next;
cur=next;
}
return newHead;
}
/**
* No.36 二叉树转为链表
* @param node
* @return
*/
private static TreeNode head = null;
private static TreeNode last = null;
public static TreeNode getTreeToList(TreeNode node){
Inorder(node);
return head;
}
private static void Inorder(TreeNode node){
if(node==null)
return;
Inorder(node.left);
if(last==null){
head=node;
last=node;
}else{
last.right=node;
node.left=last;
last=node;
}
Inorder(node.right);
}
/**
* No.37 序列化二叉树
* @param node
* @return
*/
//前序遍历
public static String serialize(TreeNode node){
if(node==null)
return "#!";
String s =node.val+"!";
s+=serialize(node.left);
s+=serialize(node.right);
return s;
}
/**
* 反序列化二叉树
* @param s
* @return
*/
public static TreeNode deSerialize(String s){
String[] ss = s.split("!");
Queue queue = new LinkedList<>();
for (String sss:ss)
queue.offer(sss);
return recover(queue);
}
private static TreeNode recover(Queue queue){
String s = queue.poll();
if(s=="#")
return null;
TreeNode node = new TreeNode(Integer.valueOf(s));
node.left=recover(queue);
node.right=recover(queue);
return node;
}
/**
* No.38 字符串排列 (字典序、重复字符)
* 递归
* @param str
* @return
*/
public static ArrayList Permutation(String str) {
ArrayList lt = new ArrayList<>();
if(str!=null&&str.length()>0) {
permutation(str.toCharArray(), 0, lt);
Collections.sort(lt);
}
return lt;
}
private static void permutation(char[] chars,int start,ArrayList lt){
if(start==chars.length){
String s = new String(chars);
/**去重*/
if(!lt.contains(s))
lt.add(s);
}else{
for(int i=start;i Combination(String s){
ArrayList lt =new ArrayList<>();
if(s!=null&&s.length()>0){
int len = s.length();
int n = 1< getCombination(String s) {
ArrayList lt = new ArrayList<>();
if (s != null && s.length() > 0) {
for (int i = 1; i <= s.length(); i++) {
combination(s,"",i,lt);
}
}
return lt;
}
public static void combination(String s,String ss,int num,ArrayList lt){
if(num==0){
lt.add(ss);
}
if(s.length()!=0&&num>0){
ss+=s.substring(0,1);
combination(s.substring(1),ss,num-1,lt);
ss=ss.substring(0,ss.length()-1);
combination(s.substring(1),ss,num,lt);
}
}
/**
* 正方体8个顶点
* @param nums
* @return
*/
public static ArrayList getEightPoints(int[] nums){
ArrayList lt = new ArrayList<>();
eightPoints(nums,0,lt);
return lt;
}
private static void eightPoints(int[] nums,int start,ArrayList lt){
if(start==nums.length){
if(check(nums)){
String s = "";
for (int i = 0; i < nums.length; i++) {
s+=nums[i];
}
if(!lt.contains(s))
lt.add(s);
}
}else{
for(int i=start;i lt = new ArrayList<>();
int[] nums = new int[n];
for (int i = 0; i < n; i++) {
nums[i]=i;
}
getNumbers(nums,0,lt);
return lt.size();
}
private static void getNumbers(int[] nums,int start,ArrayList lt){
if(start==nums.length){
String s = "";
for (int i = 0; i < nums.length; i++) {
for (int j = 0; i!=j&&j < nums.length; j++) {
if((i-j)==nums[i]-nums[j]||(i-j)==nums[j]-nums[i])
return;
}
}
for (int i = 0; i < nums.length; i++) {
s+=nums[i];
}
lt.add(s);
}else{
for (int i = start; i < nums.length; i++) {
swap(nums,start,i);
getNumbers(nums,start+1,lt);
swap(nums,start,i);
}
}
}
/**
* No.39 数组中出现次数超过一半的数
* @param nums
* @return
*/
public static int getMoreThanHalf(int[] nums){
int num=0;
int count=0;
for (int i = 0; i < nums.length; i++) {
if(count==0) {
num = nums[i];
count++;
}
else{
if(nums[i]!=num)
count--;
else
count++;
}
}
count=0;
for (int i = 0; i < nums.length; i++) {
if(nums[i]==num)
count++;
}
return count>nums.length/2?num:0;
}
/**
* 解法二
* 中位数(下标n/2处为目标数)
* @param nums
* @return
*/
public static int moreThanHalf(int[] nums){
int middle = nums.length>>1;
int start = 0;
int end = nums.length-1;
int index = partition(nums,start,end);
while (index!=middle){
if(index>middle){
end=index-1;
index=partition(nums,start,end);
}
if(indexmiddle?nums[index]:0;
}
private static int partition(int[] nums,int start,int end){
int point = nums[start];
while(startstart&&nums[end]>=point)
end--;
nums[start]=nums[end];
while(start getLeastK(int k,int[] num){
/**排序*/
// ArrayList lt = new ArrayList<>();
// if(k<0||k>num.length)
// return null;
// Arrays.sort(num);
// for(int i=0;i lt = new ArrayList<>();
if(k<1||k>num.length)
return lt;
PriorityQueue minHeap = new PriorityQueue<>(k);
for(int n:num){
minHeap.offer(n);
}
while(k-->0){
lt.add(minHeap.poll());
}
return lt;
}
/**
* No.41 数据流中的中位数
* 最大堆和最小堆
* PriorityQueue 优先队列
*/
static class DynamicArray{
// 方法一
// private static ArrayList lt = new ArrayList<>();
// public static void insert(int num){
// lt.add(num);
// }
// public static double getMedian(){
// int size = lt.size();
// if(size%2!=0)
// return lt.get(size/2)*1.0;
// else
// return (lt.get(size/2)+lt.get(size/2-1))*0.5;
// }
// 方法二
static int count;
static PriorityQueue minHeap = new PriorityQueue<>();
static PriorityQueue maxHeap = new PriorityQueue<>(new Comparator() {
@Override
public int compare(Integer o1, Integer o2) {
return o2-o1;
}
});
public static void insert(int num){
count++;
if((count&1)==0)//偶数
{
if(!maxHeap.isEmpty()&&numminHeap.peek()){
minHeap.offer(num);
num=minHeap.poll();
}
maxHeap.offer(num);
}
}
public static double getMid(){
if((count&1)==0){
return (minHeap.peek()+maxHeap.peek())/2.0;
}else{
return maxHeap.peek();
}
}
}
/**
* No.42 连续子数组的最大和
* 局部和 与 全局最大值
* @param num
* @return
*/
public static int findGreatestSumOfSubArray1(int[] num){
int sum = 0;
int max = Integer.MIN_VALUE;
for(int i =0;i{
/**
* 返回值
* 等于0,则o1等于o2;
* 大于0,则o1大于o2;
* 小于0,则o1小于o2.
* @param o1
* @param o2
* @return
*/
@Override
public int compare(String o1, String o2) {
String s1 = o1+o2;
String s2 = o2+o1;
return s1.compareTo(s2);
}
}
/**
* No.46把数字翻译成字符串
* @param num
* @return
*/
public static int getTranslationCount1(int num){
String s = num +"";
counter(0,s.length(),s,"");
return set.size();
}
public static void counter(int start,int end,String num,String res){
if(start==end){
set.add(res);
}
for (int i = start + 1; i <= end ; i++) {
String s = num.substring(start, i);
int n = Integer.valueOf(s);
if (n <= 25) {
res+=tab[n];
counter(i, end, num,res);
res=res.substring(0,res.length()-1);
}
}
}
/**
* No.46 解法二
* 动态规划
* @param s
* @return
*/
public static int getTranslationCount2(String s){
int[] dp = new int[s.length()];
for(int i=s.length()-1;i>=0;i--){
int count=0;
if(i=10&&num<=25){
if(i0)
up = dp[j];
if(j>0)
left = dp[j-1];
dp[j] = Math.max(left,up)+value[i][j];
}
}
return dp[col-1];
}
/**
* No.48最长不含重复字符的子字符串
* 动态规划
* dp[i]---以第 i 个字符结尾的最长不含重复子串长度
* @param s
* @return
*/
public static int getMaxNotRepeatedSubString(String s){
if(s==null||s.length()==0)
return 0;
int[] table = new int[256];
int[] dp = new int[s.length()];
dp[0]=1;
table[s.charAt(0)]=0;
int max = dp[0];
for(int i=1;idp[i-1])
dp[i]=dp[i-1]+1;
else
dp[i]=d;
}
table[s.charAt(i)]=i;
max = Math.max(dp[i],max);
}
return max;
}
/**
* No.49丑数
* m是n的因子,即 n % m == 0
* @param index
* @return
*/
public static int getUglyNumber(int index){
if(index==0)
return 0;
ArrayList lt=new ArrayList<>();
lt.add(1);
int i2=0,i3=0,i5=0;
while(lt.size()=begin&&right>mid){
if(nums[left]>nums[right]) {
countOfPairs += (right - mid);
temp[end--]=nums[left--];
}else{
temp[end--]=nums[right--];
}
}
while(left>=begin)
temp[end--]=nums[left--];
while(right>mid)
temp[end--]=nums[right--];
for(int i=0;i s1 = new Stack<>();
Stack s2 = new Stack<>();
while(pHead1!=null) {
s1.push(pHead1);
pHead1=pHead1.next;
}
while(pHead2!=null){
s2.push(pHead2);
pHead2=pHead2.next;
}
ListNode node1=null,node2=null;
while(!s1.isEmpty()&&!s2.isEmpty()&&s1.peek()==s2.peek()){
node1=s1.pop();
node2=s2.pop();
}
return node1;
}
/**
* No.53数字k出现的次数
* 排序数组---二分法
* @param array
* @param k
* @return
*/
public static int getNumberOfK(int[] array,int k){
int first=getFirstK(array,0,array.length-1,k);
int last=getLastK(array,0,array.length-1,k);
return first==-1?0:(last-first+1);
}
//第一个K的下标
private static int getFirstK(int[] array,int begin,int end,int k){
if(begin>end)
return -1;
int mid=(begin+end)/2;
if(array[mid]==k){
if((mid>0&&array[mid-1]!=k)||mid==0)
return mid;
else
end=mid-1;
}
else if(array[mid]end)
return -1;
int mid=(begin+end)/2;
if(array[mid]==k){
if((mid1||dif<-1)
return false;
return isBalanced(root.left)&&isBalanced(root.right);
}
/**
* 解法二
* @param root
* @return
*/
private static int getDepth(TreeNode root){
if(root==null)
return 0;
int left = getDepth(root.left);
int right = getDepth(root.right);
int dif=left-right;
if(dif>1||dif<-1){
isBalanced=false;
}
return left>right?left+1:right+1;
}
/**
* No.56数组中只出现一次的两个数字
* 解法一
* @param num
* @return
*/
public static int[] onlyTwice1(int[] num){
int[] res = new int[2];
int index = 0;
HashMap map = new HashMap<>();
for(int i=0;i>1;
bit++;
}
for(int i=0;i>bit)&1)==1?true:false;
}
/**
* No.56plus
* 只出现一次的数字(其他数字出现3次)
* 位数组
* @param num
* @return
*/
public static int onlyOnce(int[] num){
//高位在前,低位在后
int[] bitArray = new int[32];
for(int i=0;i=0;j--){
int bit=num[i]&bitMask;
if(bit!=0)
bitArray[j]+=1;
bitMask=bitMask<<1;
}
}
int res=0;
for(int i=0;i<32;i++){
res=res<<1;
res+=bitArray[i]%3;
}
return res;
}
/**
* No.57和为target的两个数
* 解法一
* @param num
* @param target
* @return
*/
public static int[] sumOfTwo(int[] num,int target){
int[] number = new int[2];
HashMap map = new HashMap<>();
for(int i=0;itarget){
last--;
}else{
first++;
}
}
return index;
}
/**
* No.57plus
* 和为s的连续正数序列
* @param m
* @param n
* @return
*/
public static ArrayList> sumOfSeq(int m,int n){
int first=1;
int last=2;
int curSum=3;
ArrayList lt = new ArrayList<>();
ArrayList> res = new ArrayList<>();
while(first(lt));
lt.clear();
last++;
curSum+=last;
}else if(curSum0;i--)
res+=str[i]+" ";
res+=str[0];
return res;
}
/**
* 翻转字符串
* 解法二
* 先翻转整个句子,再翻转每个单词
* @param s
* @return
*/
public static String reverse2(String s){
String res = reverse(s);
return res;
}
public static String reverse(String s){
String str = "";
for(int i=s.length()-1;i>=0;i--)
str+=s.charAt(i);
return str;
}
/**
* No.58plus
* 左旋转字符串
* @param s
* @param n
* @return
*/
public static String leftReverse(String s,int n){
return s.substring(n,s.length())+s.substring(0,n);
}
/**
* No.59滑动窗口最大值
* 双端队列模拟窗口
* @param num
* @param n
* @return
*/
public static ArrayList maxWindow(int[] num,int n){
ArrayList res = new ArrayList<>();
Deque queue = new LinkedList<>();
//初始窗口
for(int i=0;i=num[queue.getLast()])
queue.removeLast();
queue.addLast(i);
}
//遍历
for(int i=n;i=num[queue.getLast()])
queue.removeLast();
/**最大值过期*/
if(!queue.isEmpty()&&queue.getFirst()<=(i-n))
queue.removeFirst();
queue.addLast(i);
}
res.add(num[queue.getFirst()]);
return res;
}
/**
* No.59plus
* 具有最大值的队列
*/
public static class QueueWithMax{
private Queue queue = new LinkedList<>();
private Deque max = new LinkedList<>();
private int index = 0;
public void offer(int num){
InternalData internalData = new InternalData(num,index);
queue.offer(internalData);
while(!max.isEmpty()&&num>=max.getLast().num){
max.removeFirst();
}
max.addLast(internalData);
index++;
}
public int poll(){
/**最大值过期*/
if(max.getFirst().index==queue.peek().index)
max.removeFirst();
return queue.poll().num;
}
public int getMax(){
return max.getFirst().num;
}
/**
* 包装类
*/
private static class InternalData{
public int num;
public int index;
public InternalData(int num, int index) {
this.num = num;
this.index = index;
}
}
}
/**
* No.60
* n个骰子的点数
* @param n
*/
public static void printProbability(int n){
if(n<1)
return;
int min = n;
int max = 6*n;
int total = 6;
for(int i=1;imax){
max=cur;
}
if(price[i]0 && (sum+=addToN(n-1))>0;
return sum;
}
/**
* No.65
* 不使用四则运算实现加法
* 位运算
* 异或、位与、移位
* @param a
* @param b
* @return
*/
public static int add(int a,int b){
int sum,carry;
while(b!=0){
sum = a^b;
carry=(a&b)<<1;
a=sum;
b=carry;
}
return a;
}
/**
* No.66
* 不使用除法实现乘积数组
* @param A
* @return
*/
public static int[] multiply(int[] A){
int[] B = new int[A.length];
B[0]=1;
for(int i=1;i=0;i--){
temp *= A[i+1];
B[i] *= temp;
}
return B;
}
}