class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
if(matrix == null || matrix.length == 0){
return false;
}
boolean found = false;
if((matrix != null) && (matrix.length >0) && (matrix[0].length>0)){
int row = 0;
int column = matrix[0].length-1;
while((row < matrix.length)&&(column>=0)){
if(matrix[row][column]==target){
found = true;
break;
}else if(matrix[row][column]>target){
-- column;
}else{
++ row;
}
}
}
return found;
}
}
public class Solution {
public String replaceSpace(StringBuffer str) {
int length = str.length();
if(str == null && length <= 0){
return str.toString();
}
int originalLength = 0;
int numberOfBlank = 0;
int i = 0;
while(i<length){
++ originalLength;
if(str.charAt(i) == ‘ ‘){
++ numberOfBlank;
}
i++;
}
int newLength = originalLength + numberOfBlank*2;
str.setLength(newLength);
int indexOfOriginal = originalLength-1;
int indexOfNew = newLength-1;
while(indexOfOriginal >=0 && indexOfNew >0){
if(str.charAt(indexOfOriginal) == ‘ ‘){
str.setCharAt(indexOfNew--,‘0‘);
str.setCharAt(indexOfNew--,‘2‘);
str.setCharAt(indexOfNew--,‘%‘);
--indexOfOriginal;
}else{
str.setCharAt(indexOfNew--,str.charAt(indexOfOriginal));
--indexOfOriginal;
}
}
return str.toString();
}
}
public class Solution {
public String replaceSpace(StringBuffer str) {
for(int i=0;i<str.length();i++){
if(str.charAt(i) == ‘ ‘){
str.replace(i,i+1,"%20");
}
}
return str.toString();
}
}
1 import java.util.ArrayList;
2 import java.util.Stack;
3 public class Solution {
4 public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
5 Stack<Integer> stack=new Stack<Integer>();
6 while(listNode!=null){
7 stack.push(listNode.val);
8 listNode=listNode.next;
9 }
10
11 ArrayList<Integer> list=new ArrayList<Integer>();
12 while(!stack.isEmpty()){
13 list.add(stack.pop());
14 }
15 return list;
16 }
17 }
1 import java.util.ArrayList;
2 public class Solution {
3 ArrayList<Integer> arrayList=new ArrayList<Integer>();
4 public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
5 if(listNode!=null){
6 this.printListFromTailToHead(listNode.next);
7 arrayList.add(listNode.val);
8 }
9 return arrayList;
10 }
11 }
public class Solution {
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
TreeNode root=reConstructBinaryTree(pre,0,pre.length-1,in,0,in.length-1);
return root;
}
//前序遍历{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6}
private TreeNode reConstructBinaryTree(int [] pre,int startPre,int endPre,int [] in,int startIn,int endIn) {
if(startPre>endPre||startIn>endIn)
return null;
TreeNode root=new TreeNode(pre[startPre]);
for(int i=startIn;i<=endIn;i++)
if(in[i]==pre[startPre]){
root.left=reConstructBinaryTree(pre,startPre+1,startPre+i-startIn,in,startIn,i-1);
root.right=reConstructBinaryTree(pre,i-startIn+startPre+1,endPre,in,i+1,endIn);
break;
}
return root;
}
}
import java.util.Stack;
public class Solution {
Stack<Integer> stack1 = new Stack<Integer>();
Stack<Integer> stack2 = new Stack<Integer>();
public void push(int node) {
stack1.push(node);
}
public int pop() {
if(stack2.size()<=0){
while(stack1.size()>0){
stack2.push(stack1.pop());
}
}
return stack2.pop();
}
}
import java.util.ArrayList;
public class Solution {
public int minNumberInRotateArray(int [] array) {
if(array == null || array.length <=0){
return 0;
}
int index1 = 0;
int index2 = array.length-1;
int indexMid = index1;
while(array[index1] >= array[index2]){
if(index2 - index1 == 1){
indexMid = index2;
break;
}
indexMid = (index1+index2)/2;
if(array[indexMid] >= array[index1]){
index1 = indexMid;
}else if(array[indexMid] <= array[index2]){
index2 = indexMid;
}
}
return array[indexMid];
}
}
public class Solution {
public int Fibonacci(int n) {
int preNum=1;
int prePreNum=0;
int result=0;
if(n==0)
return 0;
if(n==1)
return 1;
for(int i=2;i<=n;i++){
result=preNum+prePreNum;
prePreNum=preNum;
preNum=result;
}
return result;
}
}
public class Solution {
public int JumpFloor(int target) {
if(target<2)
return target;
int f1=1;
int f2=0;
int f=0;
for(int i=1;i<=target;++i)
{
f=f1+f2;
f2=f1;
f1=f;
}
return f;
}
}
变态跳台阶
public class Solution {
public int JumpFloorII(int target) {
if (target <= 0) {
return -1;
} else if (target == 1) {
return 1;
} else {
return 2 * JumpFloorII(target - 1);
}
}
}
矩形覆盖
public class Solution {
public int RectCover(int target) {
if (target <= 2){
return target;
}
int pre1 = 2; // n 最后使用一块,剩下 n-1 块的写法
int pre2 = 1; // n 最后使用两块,剩下 n-2 块的写法
for (int i = 3; i <= target; i++){
int cur = pre1 + pre2;
pre2 = pre1;
pre1 = cur;
}
return pre1; //相对于 n+1 块来说,第 n 种的方法
}
}
public class Solution {
public int NumberOf1(int n) {
int count = 0;
while(n!=0)
{
n = n&(n-1);
count++;
}
return count;
}
}
循环
public class Solution {
public double Power(double base, int exponent) {
if (exponent == 0) {
return 1.0;
}
if (base - 0.0 == 0.00001 || base - 0.0 == -0.00001) {
if (exponent < 0) {
throw new RuntimeException("除0异常");
}else{
return 0.0;
}
}
int e = exponent > 0 ? exponent: -exponent;
double result = 1;
while (e != 0) {
result = (e & 1) != 0 ? result * base : result;
base *= base;
e = e >> 1;
}
return exponent > 0 ? result : 1/result;
}
}
递归
public class Solution {
public double Power(double base, int exponent) {
boolean flag = exponent < 0;
if (flag) {
exponent = -exponent;
}
double result = getPower(base, exponent);
return flag ? 1 / result : result;
}
public static double getPower(double base, int exp) {
if (exp == 0) {
return 1;
}
if (exp == 1) {
return base;
}
double ans = getPower(base, exp >> 1);
ans *= ans;
if ((exp & 1) == 1) {
ans *= base;
}
return ans;
}
}
public class Solution {
public void reOrderArray(int [] array) {
int length = array.length;
if(length == 0){
return;
}
int pBegin=0;
int pEnd = length-1;
while(pBegin < pEnd ){
while(pBegin < pEnd && (array[pBegin] & 0x1) != 0){
pBegin ++;
}
while(pBegin < pEnd && (array[pEnd] & 0x1) == 0){
pEnd--;
}
if(pBegin < pEnd){
int tmp = array[pBegin];
array[pBegin] = array[pEnd];
array[pEnd] = tmp;
}
}
}
}
拓展,牛客网多条件情况:并保证奇数和奇数,偶数和偶数之间的相对位置不变。
public class Solution {
public void reOrderArray(int [] array) {
for (int i = 0; i < array.length;i++){
for (int j = array.length - 1; j>i;j--)
{
if (array[j] % 2 == 1 && array[j - 1]%2 == 0) //前偶后奇交换
{
int tmp = array[j];
array[j] = array[j-1];
array[j-1] = tmp;
}
}
}
}
}
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
public class Solution {
public ListNode FindKthToTail(ListNode head,int k) {
if(head == null || k==0){
return null;
}
ListNode pAhead = head;
ListNode pBehind = null;
for(int i=0;i<k-1;++i){
if(pAhead.next != null){
pAhead = pAhead.next;
}else{
return null;
}
}
pBehind = head;
while(pAhead.next != null){
pAhead = pAhead.next;
pBehind = pBehind.next;
}
return pBehind;
}
}
求链表中间结点
从链表头结点出发,一个指针走一步,一个指针走两步。
判断词汇表单向链表是否形成了环形结构。同上一个,如果走的快的指针追上了走得慢的指针,就是;如果走到链表末尾(next指向null),就不是。
应用--leetcode题目 141. 环形链表
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public boolean hasCycle(ListNode head) {
if(head == null || head.next == null ){
return false;
}
ListNode ahead = head.next;
ListNode behind = head;
while(ahead != behind){
if(ahead.next == null || ahead.next.next == null){
return false;
}
ahead = ahead.next.next;
behind = behind.next;
}
return true;
}
}
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
ArrayList<Integer> arrayList=new ArrayList<Integer>();
public ListNode reverseList(ListNode head) {
ListNode reversedHead = null;
ListNode node = head;
ListNode prenode = null;
while(node != null){
ListNode next = node.next;
if(next == null){
reversedHead = node;
}
node.next = prenode;
prenode = node;
node = next;
}
return reversedHead;
}
}
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if(l1 == null){
return l2;
}
if(l2 == null){
return l1;
}
ListNode mergeHead = null;
if(l1.val >= l2.val){
mergeHead = l2;
mergeHead.next = mergeTwoLists(l1,l2.next);
}else{
mergeHead = l1;
mergeHead.next = mergeTwoLists(l2,l1.next);
}
return mergeHead;
}
}
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public boolean HasSubtree(TreeNode root1,TreeNode root2) {
boolean result = false;
if(root1 != null && root2 != null){
if(root1.val == root2.val){
result = DoesTree1HasTree2(root1,root2);
}
if(!result){
result = HasSubtree(root1.left,root2);
}
if(!result){
result = HasSubtree(root1.right,root2);
}
}
return result;
}
boolean DoesTree1HasTree2(TreeNode root1,TreeNode root2){
if(root2 == null){
return true;
}
if(root1 == null){
return false;
}
if(root1.val!= root2.val){
return false;
}
return DoesTree1HasTree2(root1.left,root2.left)&&
DoesTree1HasTree2(root1.right,root2.right);
}
}
19 二叉树的镜像
递归实现
public class Solution {
public void Mirror(TreeNode root) {
if(root == null ||
(root.left == null && root.right == null)){
return;
}
TreeNode temp = root.left;
root.left = root.right;
root.right = temp;
if(root.left != null){
Mirror(root.left);
}
if(root.right != null){
Mirror(root.right);
}
}
}
循环实现
import java.util.Stack;
public class Solution {
public void Mirror(TreeNode root) {
if(root == null){
return;
}
Stack<TreeNode> stack = new Stack<TreeNode>();
stack.push(root);
while(!stack.isEmpty()){
TreeNode node = stack.pop();
if(node.left != null||node.right != null){
TreeNode temp = node.left;
node.left = node.right;
node.right = temp;
}
if(node.left!=null){
stack.push(node.left);
}
if(node.right!=null){
stack.push(node.right);
}
}
}
}
20 顺时针打印矩阵
import java.util.ArrayList;
public class Solution {
public ArrayList<Integer> printMatrix(int [][] matrix) {
ArrayList<Integer> result = new ArrayList<Integer> ();
if(matrix.length==0) return result;
int row = matrix.length,col = matrix[0].length;
if(col==0) return result;
// 定义四个关键变量,表示左上和右下的打印范围
int left = 0, top = 0, right = col - 1, bottom = row - 1;
while(left <= right && top <= bottom){
// left to right
for (int i = left; i <= right; ++i) result.add(matrix[top][i]);
// top to bottom
for (int i = top + 1; i <= bottom; ++i) result.add(matrix[i][right]);
// right to left
if (top != bottom)
for (int i = right - 1; i >= left; --i) result.add(matrix[bottom][i]);
// bottom to top
if (left != right)
for (int i = bottom - 1; i > top; --i) result.add(matrix[i][left]);
left++;top++;right--;bottom--;
}
return result;
}
}
class Solution {
public:
vector<int> printMatrix(vector<vector<int> > matrix) {
int row = matrix.size();
int col = matrix[0].size();
vector<int> res;
// 输入的二维数组非法,返回空的数组
if (row == 0 || col == 0) return res;
// 定义四个关键变量,表示左上和右下的打印范围
int left = 0, top = 0, right = col - 1, bottom = row - 1;
while (left <= right && top <= bottom)
{
// left to right
for (int i = left; i <= right; ++i) res.push_back(matrix[top][i]);
// top to bottom
for (int i = top + 1; i <= bottom; ++i) res.push_back(matrix[i][right]);
// right to left
if (top != bottom)
for (int i = right - 1; i >= left; --i) res.push_back(matrix[bottom][i]);
// bottom to top
if (left != right)
for (int i = bottom - 1; i > top; --i) res.push_back(matrix[i][left]);
left++,top++,right--,bottom--;
}
return res;
}
};
21 包含min函数的栈
Stack实现
import java.util.Stack;
public class Solution {
Stack<Integer> stack1 = new Stack<Integer>();
Stack<Integer> stack2 = new Stack<Integer>();
public void push(int node) {
stack1.push(node);
if(stack2.isEmpty() || node < stack2.peek()){
stack2.push(node);
}else{
stack2.push(stack2.peek());
}
}
public void pop() {
assert(!stack1.isEmpty() && !stack2.isEmpty());
stack1.pop();
stack2.pop();
}
public int top() {
return stack1.peek();
}
public int min() {
return stack2.peek();
}
}
ArrayList实现
import java.util.ArrayList;
public class Solution {
ArrayList<Integer> list = new ArrayList<Integer>();
public void push(int node) {
list.add(0,node);
}
public void pop() {
list.get(0);
list.remove(0);
}
public int top() {
return list.get(0).intValue();
}
public int min() {
int temp = top();
for(int i=1;i<list.size();i++){
if(temp>list.get(i).intValue()){
temp = list.get(i).intValue();
}
}
return temp;
}
}
22 栈的压入、弹出序列
Stack实现
import java.util.ArrayList;
import java.util.Stack;
public class Solution {
public boolean IsPopOrder(int [] pushA,int [] popA) {
boolean bResult = false;
int nLength = pushA.length;
if(pushA != null && popA != null && nLength>0){
int nextpush =0;
int nextpop = 0;
Stack<Integer> stackData = new Stack<Integer>();
while(nextpop < nLength){
while(stackData.empty() || stackData.peek() != popA[nextpop]){
if(nextpush == nLength){
break;
}
stackData.push(pushA[nextpush]);
nextpush++;
}
if(stackData.peek() != popA[nextpop]){
break;
}
stackData.pop();
nextpop++;
}
if(stackData.empty() && nextpop == nLength){
bResult = true;
}
}
return bResult;
}
}
23 从上往下打印二叉树
按层打印,实际就是广度优先搜索 BFS, 借助一个队列就可以实现.
广度优先搜索 BFS:主要借助一个队列、一个布尔类型数组、邻接矩阵完成(判断一个点是否查看过,用于避免重复到达同一个点,造成死循环等),先将各点以及各点的关系存入邻接矩阵。
再从第一个点开始,将一个点存入队列,然后在邻接表中找到他的相邻点,存入队列,每次pop出队列头部并将其打印出来(文字有些抽象,实际过程很简单),整个过程有点像往水中投入石子水花散开。
public class Solution {
public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) {
ArrayList<Integer> list = new ArrayList<>();
ArrayList<TreeNode> queue = new ArrayList<>();
if (root == null) {
return list;
}
queue.add(root);
while (queue.size() != 0) {
TreeNode temp = queue.remove(0);
if (temp.left != null){
queue.add(temp.left);
}
if (temp.right != null) {
queue.add(temp.right);
}
list.add(temp.val);
}
return list;
}
}
扩展:
广度优先遍历一个有向图,同样可以基于队列实现。树是图的一种特殊退化形式,从上到下按层遍历二叉树,本质上就是广度优先遍历二叉树。
24 二叉搜索树的后序遍历序列
后序遍历:先遍历子结点,再遍历父结点。在后序遍历得到的序列中,最后一个数字是树的根结点。
public class Solution {
public boolean VerifySquenceOfBST(int [] sequence) {
if(sequence == null || sequence.length <= 0){
return false;
}
int root = sequence[sequence.length-1];
int[] sequenceleft = new int[sequence.length];
int[] sequenceright = new int[sequence.length];
//在二叉搜索树中左子树的结点小于结点
int i=0;
for(;i<sequence.length -1;++i){
if(sequence[i] > root){
break;
}
sequenceleft[i] = sequence[i];
}
//早二叉搜索树中右子树的结点大于根结点
int j=i;
int k=0;
for(;j < sequence.length -1;++j){
if(sequence[j] < root){
return false;
}
k++;
sequenceright[k] = sequence[j];
}
//判断左子树是不是二叉搜索树
boolean left = true;
if(i>0){
left = VerifySquenceOfBST(sequenceleft);
}
boolean right = true;
if(i<sequence.length-1){
right = VerifySquenceOfBST(sequenceright);
}
return (left && right);
}
}
前中后序遍历

前、中、后指的是根节点的顺序。前序遍历有根节点开始。
前序遍历:ABCDEFGHK
中序遍历:BDCAEHGKF
后序遍历:DCBHKGFEA
中序排列思想:

25 二叉树中和为某一值的路径
public class Solution {
public ArrayList<ArrayList<Integer>> FindPath(TreeNode root,int target) {
ArrayList<ArrayList<Integer>> paths=new ArrayList<ArrayList<Integer>>();
if(root==null)return paths;
find(paths,new ArrayList<Integer>(),root,target);
return paths;
}
public void find(ArrayList<ArrayList<Integer>> paths,ArrayList<Integer> path,TreeNode root,int target){
path.add(root.val);
if(root.left==null&&root.right==null){
if(target==root.val){
paths.add(path);
}
return;
}
ArrayList<Integer> path2=new ArrayList<>();
path2.addAll(path);
if(root.left!=null)find(paths,path,root.left,target-root.val);
if(root.right!=null)find(paths,path2,root.right,target-root.val);
}
}
import java.util.ArrayList;
import java.util.Stack;
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public ArrayList<ArrayList<Integer>> FindPath(TreeNode root,int target) {
ArrayList<ArrayList<Integer>> pathList=
new ArrayList<ArrayList<Integer>>();
if(root==null)
return pathList;
Stack<Integer> stack=new Stack<Integer>();
FindPath(root,target,stack,pathList );
return pathList;
}
private void FindPath(TreeNode root, int target,
Stack<Integer> path,
ArrayList<ArrayList<Integer>> pathList) {
if(root==null)
return;
if(root.left==null&&root.right==null){
if(root.val==target){
ArrayList<Integer> list=
new ArrayList<Integer>();
for(int i:path){
list.add(new Integer(i));
}
list.add(new Integer(root.val));
pathList.add(list);
}
}
else{
path.push(new Integer(root.val));
FindPath(root.left, target-root.val, path, pathList);
FindPath(root.right, target-root.val, path, pathList);
path.pop();
}
}
}
26 复杂链表的复制
分治法,通常分治法的思路都可以用递归实现
在复杂链表的结点中,除了有指向下一个结点的指针,还有指向任意结点的指针。、
/*
public class RandomListNode {
int label;
RandomListNode next = null;
RandomListNode random = null;
RandomListNode(int label) {
this.label = label;
}
}
*/
public class Solution {
public RandomListNode Clone(RandomListNode pHead)
{
CloneNodes(pHead);
ConnectSiblingNodes(pHead);
return ReconnectNodes(pHead);
}
void CloneNodes(RandomListNode pHead){
RandomListNode pNode = pHead;
while(pNode != null){
RandomListNode pCloned = new RandomListNode(pNode.label);
pCloned.next = pNode.next;
pCloned.random = null;
pNode.next = pCloned;
pNode = pCloned.next;
}
}
void ConnectSiblingNodes(RandomListNode pHead){
RandomListNode pNode = pHead;
while(pNode!= null){
RandomListNode pCloned = pNode.next;
if(pNode.random != null){
pCloned.random = pNode.random.next;
}
pNode = pCloned.next;
}
}
RandomListNode ReconnectNodes(RandomListNode pHead){
RandomListNode pNode = pHead;
RandomListNode pClonedHead = null;
RandomListNode pClonedNode = null;
if(pNode != null){
pClonedNode = pNode.next;
pClonedHead = pClonedNode;
pNode.next = pClonedNode.next;
pNode = pNode.next;
}
while(pNode != null){
pClonedNode.next = pNode.next;
pClonedNode = pClonedNode.next;
pNode.next = pClonedNode.next;
pNode = pNode.next;
}
return pClonedHead;
}
}
27 二叉搜索树与双向链表
二叉搜索树:左子结点的值小于父结点的值,右子节点的值大于父结点的值。
直接递归
public class Solution {
public TreeNode Convert(TreeNode pRootOfTree) {
if(pRootOfTree == null) return pRootOfTree;
pRootOfTree = ConvertNode(pRootOfTree);
while(pRootOfTree.left!= null) pRootOfTree = pRootOfTree.left;
return pRootOfTree;
}
TreeNode ConvertNode(TreeNode root)
{
if(root == null) return root;
if(root.left != null)
{
TreeNode left = ConvertNode(root.left);
while(left.right!= null) left = left.right;
left.right = root;
root.left = left;
}
if(root.right != null)
{
TreeNode right = ConvertNode(root.right);
while(right.left!= null) right = right.left;
right.left = root;
root.right = right;
}
return root;
}
}
此解法暂时未通过
public class Solution {
public TreeNode Convert(TreeNode pRootOfTree) {
TreeNode pLastNodeInList = null;
ConvertNode(pRootOfTree, pLastNodeInList);
//pLastNodeInList双向链表尾结点
//需要返回头结点
TreeNode pHeadOfList = pLastNodeInList;
while(pHeadOfList != null && pHeadOfList.left != null){
pHeadOfList = pHeadOfList.left;
}
return pHeadOfList;
}
void ConvertNode(TreeNode pNode, TreeNode pLastNodeInList){
if(pNode == null){
return;
}
TreeNode pCurrent = pNode;
if(pCurrent.left != null){
ConvertNode(pCurrent.left, pLastNodeInList);
}
pCurrent.left = pLastNodeInList;
if(pLastNodeInList != null){
pLastNodeInList.right = pCurrent;
}
pLastNodeInList = pCurrent;
if(pCurrent.right != null){
ConvertNode(pCurrent.right,pLastNodeInList);
}
}
}
28 字符串的排列
解法一:递归
import java.util.ArrayList;
import java.util.Collections;
import java.util.Set;
import java.util.HashSet;
public class Solution {
public ArrayList<String> Permutation(String str) {
ArrayList<String> list = new ArrayList<String>();
if(str!=null && str.length()>0){
PermutationHelper(str.toCharArray(),0,list);
Collections.sort(list);
}
return list;
}
private void PermutationHelper(char[] chars,int i,ArrayList<String> list){
if(i == chars.length-1){
list.add(String.valueOf(chars));
}else{
Set<Character> charSet = new HashSet<Character>();
for(int j=i;j<chars.length;++j){
if(j==i || !charSet.contains(chars[j])){
charSet.add(chars[j]);
swap(chars,i,j);
PermutationHelper(chars,i+1,list);
swap(chars,j,i);
}
}
}
}
private void swap(char[] cs,int i,int j){
char temp = cs[i];
cs[i] = cs[j];
cs[j] = temp;
}
}
解法二:字典序排列算法
import java.util.ArrayList;
import java.util.Arrays;
public class Solution {
public ArrayList<String> Permutation(String str) {
ArrayList<String> list = new ArrayList<String>();
if(str==null || str.length()==0){
return list;
}
char[] chars = str.toCharArray();
Arrays.sort(chars);
list.add(String.valueOf(chars));
int len = chars.length;
while(true){
int lIndex = len-1;
int rIndex;
while(lIndex>=1 && chars[lIndex-1]>=chars[lIndex]){
lIndex--;
}
if(lIndex == 0)
break;
rIndex = lIndex;
while(rIndex<len && chars[rIndex]>chars[lIndex-1]){
rIndex++;
}
swap(chars,lIndex-1,rIndex-1);
reverse(chars,lIndex);
list.add(String.valueOf(chars));
}
return list;
}
private void reverse(char[] chars,int k){
if(chars==null || chars.length<=k)
return;
int len = chars.length;
for(int i=0;i<(len-k)/2;i++){
int m = k+i;
int n = len-1-i;
if(m<=n){
swap(chars,m,n);
}
}
}
private void swap(char[] cs,int i,int j){
char temp = cs[i];
cs[i] = cs[j];
cs[j] = temp;
}
}
29 数组中出现次数超过一半的数字
方法1:
import java.util.Arrays;
public class Solution {
public int MoreThanHalfNum_Solution(int [] array) {
Arrays.sort(array);
int count=0;
for(int i=0;i<array.length;i++){
if(array[i]==array[array.length/2]){
count++;
}
}
if(count>array.length/2){
return array[array.length/2];
}else{
return 0;
}
}
}
方法2:HashMap
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class Solution {
public int MoreThanHalfNum_Solution(int [] array) {
HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();
for(int i=0;i<array.length;i++){
if(!map.containsKey(array[i])){
map.put(array[i],1);
}else{
int count = map.get(array[i]);
map.put(array[i],++count);
}
}
Iterator iter = map.entrySet().iterator();
while(iter.hasNext()){
Map.Entry entry = (Map.Entry)iter.next();
Integer key =(Integer)entry.getKey();
Integer val = (Integer)entry.getValue();
if(val>array.length/2){
return key;
}
}
return 0;
}
}
方法3:快排思想--未通过
public class Solution {
public int MoreThanHalfNum_Solution(int [] array) {
if(array.length<=0)
return 0;
int start = 0;
int length = array.length;
int end = length-1;
int middle = length>>1;
int index = Partition(array,start,end);
while(index!=middle){
if(index>middle){
index = Partition(array,start,index-1);
}
else{
index = Partition(array,index+1,end);
}
}
int result = array[middle];
int times = 0;
for(int i=0;i<length;++i){
if(array[i] == result)
times++;
}
if(times*2<length){
System.out.println(times);
return 0;
}else{
return result;
}
}
public int Partition(int[] array,int start,int end){
int flag = (array[start]+array[end])/2;
while(start<end){
while(array[end]>flag){
end--;
}
swap(array,start,end);
while(array[start]<=flag){
start++;
}
swap(array,start,end);
}
return start;
}
public void swap(int[] array,int num1,int num2){
int temp =array[num1];
array[num1] =array[num2];
array[num2] =temp;
}
}
30 最小的K个数
解法一:冒泡排序
import java.util.ArrayList;
public class Solution {
public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
ArrayList<Integer> al = new ArrayList<Integer>();
if (k > input.length) {
return al;
}
for (int i = 0; i < k; i++) {
for (int j = 0; j < input.length - i - 1; j++) {
if (input[j] < input[j + 1]) {
int temp = input[j];
input[j] = input[j + 1];
input[j + 1] = temp;
}
}
al.add(input[input.length - i - 1]);
}
return al;
}
}
解法2:利用快速排序中的获取分割(中轴)点位置函数getPartitiion--用例未通过
import java.util.ArrayList;
public class Solution {
public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
ArrayList<Integer> result = new ArrayList<Integer>();
if(input==null || k>input.length || k<=0) return result;
int start = 0;
int end = input.length-1;
int index = getPartition(input,start,end);
while(index != (k-1))
{
if(index > (k-1))
{
end = index - 1;
index = getPartition(input,start,end);
}
else
{
start = index + 1;
index = getPartition(input,start,end);
}
}
for(int i=0;i<k;++i)
{
result.add(input[i]);
}
return result;
}
public void swap(int fir,int sec)
{
int temp = fir;
fir = sec;
sec = temp;
}
public int getPartition(int [] input,int start,int end)
{
if(input==null || start>end) return -1;
int temp = input[end];
int j = start - 1;
for(int i=start;i<end;++i)
{
if(input[i]<=temp)
{
++j;
if(i!=j) swap(input[i],input[j]);
}
}
swap(input[j+1],input[end]);
return (j+1);
}
}
31 连续子数组的最大和
解法1:分析数组规律
public class Solution {
public int FindGreatestSumOfSubArray(int[] array) {
int len = array.length;
if(array==null || len<0){
return 0;
}
int nCurSum = 0;
int nGreatestSum = 0x80000000;
for(int i=0; i<len;i++){
if(nCurSum <= 0){
nCurSum = array[i];
}else{
nCurSum += array[i];
}
if(nCurSum > nGreatestSum){
nGreatestSum = nCurSum;
}
}
return nGreatestSum;
}
}
解法2:动态规划思想,代码一致
32 从1到n整数中1出现的次数
public class Solution {
public int NumberOf1Between1AndN_Solution(int n) {
int number = 0;
for(int i=0;i<=n;i++){
number += numberOf1(i);
}
return number;
}
public int numberOf1(int n){
int number = 0;
while(n>0){
if(n%10 == 1){
number ++;
}
n = n/10;
}
return number;
}
}
33 把数组排成最小的数
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class Solution {
public String PrintMinNumber(int [] numbers) {
int n;
String s="";
ArrayList<Integer> list= new ArrayList<Integer>();
n=numbers.length;
for(int i=0;i<n;i++){
list.add(numbers[i]);
}
Collections.sort(list, new Comparator<Integer>(){
public int compare(Integer str1,Integer str2){
String s1=str1+""+str2;
String s2=str2+""+str1;
return s1.compareTo(s2);
}
});
for(int j:list){
s+=j;
}
return s;
}
}
import java.util.ArrayList;
public class Solution {
public String PrintMinNumber(int [] numbers) {
String str = "";
for (int i=0; i<numbers.length; i++){
for (int j=i+1; j<numbers.length; j++){
int a = Integer.valueOf(numbers[i]+""+numbers[j]);
int b = Integer.valueOf(numbers[j]+""+numbers[i]);
if (a > b){
int t = numbers[i];
numbers[i] = numbers[j];
numbers[j] = t;
}
}
}
for (int i = 0; i < numbers.length; i++) {
str += String.valueOf(numbers[i]);
}
return str;
}
}
34 丑数
解法一:暴力破解 超时
public class Solution {
public int GetUglyNumber_Solution(int index) {
if(index <= 0){
return 0;
}
int number = 0;
int uglyFound = 0;
while(uglyFound < index){
++number;
if(IsUgly(number)){
++uglyFound;
}
}
return number;
}
boolean IsUgly(int number){
while(number % 2 == 0){
number /= 2;
}
while(number % 3 == 0){
number /= 3;
}
while(number % 5 == 0){
number /= 5;
}
return (number==1)?true:false;
}
}
方法二:创建数组保存已找到的丑数,用空间换时间
public class Solution {
public int GetUglyNumber_Solution(int index) {
if(index <=0){
return 0;
}
int[] uglyNums = new int[index];
uglyNums[0]=1;
int nextUglyIndex = 1;
int mul2 = 0;
int mul3 = 0;
int mul5 = 0;
while(nextUglyIndex < index){
int min = Min(uglyNums[mul2]*2, uglyNums[mul3]*3, uglyNums[mul5]*5);
uglyNums[nextUglyIndex] = min;
while(uglyNums[mul2]*2 <= uglyNums[nextUglyIndex]){
++mul2;
}
while(uglyNums[mul3]*3 <= uglyNums[nextUglyIndex]){
++mul3;
}
while(uglyNums[mul5]*5 <= uglyNums[nextUglyIndex]){
++mul5;
}
++nextUglyIndex;
}
int ugly = uglyNums[nextUglyIndex - 1];
return ugly;
}
int Min(int num1, int num2, int num3){
int min = (num1 <= num2)?num1:num2;
min = (min <= num3)?min:num3;
return min;
}
}
35 第一个只出现一次的字符
方法1:哈希表 ASCII码
public class Solution {
public int FirstNotRepeatingChar(String str) {
int[] words = new int[58];
for(int i = 0;i<str.length();i++){
words[((int)str.charAt(i))-65] += 1;
}
for(int i=0;i<str.length();i++){
if(words[((int)str.charAt(i))-65]==1)
return i;
}
return -1;
}
}
方法2:字符串函数 第一次和最后一次出现的位置相同
public class Solution {
public int FirstNotRepeatingChar(String str) {
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
if (str.indexOf(ch) == str.lastIndexOf(ch))
return i;
}
return -1;
}
}
***相似题目*** 统计多个字符是不是在字符串出现过或者次数
删除第一个字符串中在第二个字符串中出现的字符
删除字符串中所有重复出现的字符
变位词
36 数组中的逆序对
方法1:归并排序 按书上代码没有通过用例
public class Solution {
public int InversePairs(int [] array) {
if(array == null || array.length <0){
return 0;
}
int len = array.length;
int[] copy = new int[len];
for(int i=0;i<len;++i){
copy[i] = array[i];
}
int count = InversePairsCore(array,copy,0,len-1);
return count;
}
int InversePairsCore(int[] array, int[] copy, int start, int end){
if(start == end){
copy[start] = array[start];
return 0;
}
int len = (end - start)/2;
int left = InversePairsCore(copy, array, start, start + len);
int right = InversePairsCore(copy, array, start + len+1,end);
int i =start +len;
int j=end;
int indexCopy = end;
int count = 0;
while(i>= start && j >= start + len+ 1){
if(array[i] > array[j]){
copy[indexCopy--] = array[i--];
count += j-start-len;
}else{
copy[indexCopy--] = array[j--];
}
}
for(;i>=start;--i){
copy[indexCopy--] = array[i];
}
for(;j>= start + len +1;--j){
copy[indexCopy] = array[j];
}
return left+right+count;
}
}
37 两个链表的第一个公共结点
public class Solution {
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
int len1 = GetListLen(pHead1);
int len2 = GetListLen(pHead2);
int lendif = len1-len2;
ListNode headLong = pHead1;
ListNode headShort = pHead2;
if(len2>len1){
headLong = pHead1;
headShort = pHead2;
lendif = len2-len1;
}
for(int i=0;i<lendif;++i){
headLong = headLong.next;
}
while(headLong != null && headShort != null && headLong != headShort){
headLong = headLong.next;
headShort = headShort.next;
}
ListNode firstCommNode = headLong;
return firstCommNode;
}
int GetListLen(ListNode pHead){
int len = 0;
ListNode pNode = pHead;
while(pNode != null){
++ len;
pNode = pNode.next;
}
return len;
}
}
38 数字在排序数组中出现的次数
方法1:二分法:
public class Solution {
public int GetNumberOfK(int [] array , int k) {
int number = 0;
int len = array.length;
if(array != null && len >0){
int first = GetFirstK(array, len,k, 0,len-1);
int last = GetLastK(array, len,k,0,len-1);
if(first > -1 && last > -1){
number = last-first+1;
}
}
return number;
}
int GetFirstK(int[] array, int length, int k, int start, int end){
if(start > end){
return -1;
}
int midIndex = (start + end)/2;
int midData = array[midIndex];
if(midData == k){
if((midIndex > 0 && array[midIndex -1] != k) || midIndex==0){
return midIndex;
}else{
end = midIndex -1;
}
}else if(midData > k){
end = midIndex - 1;
}else{
start = midIndex +1;
}
return GetFirstK(array, length, k, start, end);
}
int GetLastK(int[] array, int length, int k, int start, int end){
if(start > end){
return -1;
}
int midIndex = (start + end)/2;
int midData = array[midIndex];
if(midData == k){
if((midIndex <length-1 && array[midIndex + 1] != k) || midIndex==length-1){
return midIndex;
}else{
start = midIndex + 1;
}
}else if(midData < k){
start = midIndex +1;
}else{
end = midIndex - 1;
}
return GetLastK(array, length, k, start, end);
}
}
39 二叉树的深度
public class Solution {
public int TreeDepth(TreeNode root) {
if(root == null){
return 0;
}
int left = TreeDepth(root.left);
int right = TreeDepth(root.right);
return (left>right)?(left+1):(right+1);
}
}
****拓展:平衡二叉树
二叉树中任意结点的左右子树的深度相差不超过1就是平衡二叉树。
解法1:
public class Solution {
public boolean IsBalanced_Solution(TreeNode root) {
if(root == null){
return true;
}
int left = TreeDepth(root.left);
int right = TreeDepth(root.right);
int diff = left-right;
if(diff > 1 || diff < -1){
return false;
}
return IsBalanced_Solution(root.left) && IsBalanced_Solution(root.right);
}
public int TreeDepth(TreeNode root) {
if(root == null){
return 0;
}
int left = TreeDepth(root.left);
int right = TreeDepth(root.right);
return (left>right)?(left+1):(right+1);
}
}
解法2:每个结点遍历一次 ---未通过所有用例
public class Solution {
public boolean IsBalanced_Solution(TreeNode root) {
int depth = 0;
return IsBalanced_Solution(root, depth);
}
public boolean IsBalanced_Solution(TreeNode root, int depth) {
if(root == null){
depth = 0;
return true;
}
int left=depth;
int right=depth;
if(IsBalanced_Solution(root.left, left) && IsBalanced_Solution(root.right, right)){
int diff = left - right;
if(diff <= 1 && diff >= -1){
depth = 1+(left>right ? left:right);
return true;
}
}
return false;
}
}
40 数组中只出现一次的数字
--未通过
//num1,num2分别为长度为1的数组。传出参数
//将num1[0],num2[0]设置为返回结果
public class Solution {
public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
if(array.length < 2){
return;
}
if(array.length == 2){
num1[0] = array[0];
num2[0] = array[1];
return;
}
int resultExclusiveOR = array[0];
for(int i=0; i<array.length; ++i){
resultExclusiveOR ^= array[i];
}
int indexOf1 = FindFirstBitIs1(resultExclusiveOR);
for(int j=0; j<array.length;++j){
if(IsBit1(array[j],indexOf1)){
num1[j] ^= array[j];
}else{
num2[j] ^= array[j];
}
}
}
int FindFirstBitIs1(int num){
int indexBit = 0;
while((num &1)==0 && indexBit < 32){
num = num >>1;
indexBit++ ;
}
return indexBit;
}
boolean IsBit1(int num, int indexBit){
num = num >> indexBit;
return (num&1) == 1;
}
}
41 和为s的两个数字 VS 和为s的连续正数序列
42 反转单词顺序 VS 左旋转字符串
43 n个骰子的点数
44 扑克牌的顺子
45 圆圈中最后剩下的数字
46 求1+2+...+n
47 不用加减乘除做加法
48 不能被继承的类
49 把字符串转换成整数
50 书中两个结点的最低公共祖先
原文:https://www.cnblogs.com/coding-fairyland/p/12968759.html