目录
二叉树的前序、中序、后续、遍历
二叉树的结构
第一次到达该节点,就放入节点值到结果中,是前序遍历,
第二次到达该节点,就放入节点值到结果中,是中序遍历,
第三次到达该节点,就放入节点值到结果中,是后序遍历,
将链表转化为二叉树
public class TreeNode {
TreeNode left,right;
int val;
public TreeNode(int val) {
this.left = this.right = null;
this.val = val;
}
public TreeNode(TreeNode treeNode){
this.left = treeNode.left;
this.right = treeNode.right;
this.val = treeNode.val;
}
public static void main(String args[]){
List<String> list = new ArrayList<String>( );
list.add( "2" );
list.add( "1" );
list.add( "4" );
list.add( "#" );
list.add( "#" );
list.add( "3" );
list.add( "5" );
TreeNode root = treeConstruct( list );
int i=0;
}
/**
* 由链表构建二叉树
* @param list
* @return
*/
public static TreeNode treeConstruct(List<String> list){
TreeNode root = new TreeNode( Integer.valueOf( list.get( 0 ) ) );//先构造根节点
TreeNode p = root;
TreeNode curLeft,curRight;
Queue<TreeNode> queue = new LinkedList<TreeNode>( );
queue.add( p );
TreeNode temp = queue.peek();
int pos = 0;
while(pos+1 <list.size()-1) {
int size = queue.size();
int pp = pos;
for (int i = pos; i < pp+size*2; i += 2) {//在数组中取数,每次增加2,因为有左右俩节点
p = queue.poll();//remove and return head
if ( pos + 1 < list.size()&&!list.get( pos + 1 ).equals( "#" ) ) {
curLeft = new TreeNode( Integer.valueOf( list.get( pos + 1 ) ) );
p.left = curLeft ;
queue.add( p.left );
}
if ( pos + 2 < list.size()&&!list.get( pos + 2 ).equals( "#" )) {
curRight = new TreeNode( Integer.valueOf( list.get( pos + 2 ) ) );
p.right = curRight ;
queue.add( p.right );
}
pos+=2;
}
}
return temp;
}
}
public class TreeNode {
public int val;
public TreeNode left, right;
public TreeNode(int val) {
this.val = val;
this.left = this.right = null;
}
}
递归算法
{
ArrayList<Integer> ret=new ArrayList<Integer>();
TreeNode p=root;
PreOrderTree(ret,p);
return ret;
}
void PreOrderTree(ArrayList<Integer> ret,TreeNode p){
if(p==null)
return ;
ret.add(p.val);//这一步的位置,确定了是前序、中序、后续
PreOrderTree(ret,p.left);
PreOrderTree(ret,p.right);
}
}
非递归的方法
主要使用栈(stack)返回到上一节点。‘
前序遍历的非递归方法
List<Integer> ret=new ArrayList<Integer>();
Stack<TreeNode> sta=new Stack<TreeNode>();
if(root==null)
return ret;
TreeNode p=root;
while(p!=null || !sta.empty()){
ret.add(p.val);
sta.push(p);
p=p.left;
//左节点为空,找到已存栈中第一个有右节点,再由该右节点再次循环从左开始查
while(p==null && !sta.empty()){
p=sta.pop().right;
}
}
return ret;
中序遍历的非递归
public List<Integer> inorderTraversal(TreeNode root) {
// write your code here
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode p = root;
List<Integer> ret = new ArrayList<Integer>();
if(root == null){
return ret;
}
while(p!=null || !stack.empty()){
stack.push(p);
p=p.left;
while(p==null && !stack.empty()){
//因为中序遍历是第二次经过节点,所以从由节点取出的时候记录值
p = stack.pop();
ret.add(p.val);
p=p.right;
}
}
return ret;
}
后序遍历的非递归
添加右节点被访问过的标记
public List<Integer> postorderTraversal(TreeNode root) {
// write your code here
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode flag=null ;
List<Integer> ret = new ArrayList<Integer>();
TreeNode p = root;
if(root ==null){
return ret;
}
while(p!=null){//放入所有的左节点
stack.push(p);
p=p.left;
}
while(!stack.empty()){
p=stack.pop();
if(p.right==null||p.right==flag){//右节点已经被访问过或为空
ret.add(p.val);
flag = p;
}else{
stack.push(p);
p=p.right;
while(p!=null){
stack.push(p);
p=p.left;
}
}
}
return ret;
}
二叉树的层次遍历
public List<List<Integer>> levelOrder(TreeNode root) {
// write your code here
List<List<Integer>> ret = new ArrayList<List<Integer>>();
Queue<TreeNode> queue = new LinkedList<TreeNode>();
if(root == null){
return ret ;
}
TreeNode p = root;
queue.add(root);
while(!queue.isEmpty()){
List<Integer> temp = new ArrayList <Integer>();
int size = queue.size();
for(int i=0;i<size;i++){//这里不能写成i<queue.size();大小是变化的
p=queue.poll();
temp.add(p.val);
if(p.left!=null){
queue.add(p.left);
}
if(p.right!=null){
queue.add(p.right);
}
}
ret.add(temp);
}
return ret;
}
二叉树的路径和
这个地方注意java中new 的对象,在使用的时候是使用地址引用的(传址),所以需要创建副本,不然存的对象都会是一个。
public List<List<Integer>> binaryTreePathSum(TreeNode root, int target) {
// write your code here
List<List<Integer>> listAll = new ArrayList<List<Integer>>();
List<Integer> list = new ArrayList<Integer>();
TreeNode p = root;
if(root == null ){
return listAll;
}
findPath(listAll,list,p,target);
return listAll;
}
void findPath(List<List<Integer>> listAll,List<Integer> list, TreeNode p , int target){
list.add(p.val);
if(p.left == null && p.right == null){
if(isRightPath(list,target)){
listAll.add(new ArrayList(list));
//这个地方要注意,如果不是新建的话结果会发现结果集相同
return ;
}
}
if(p.left != null){
findPath(listAll,list,p.left,target);
list.remove(list.size()-1);
}
if(p.right != null){
findPath(listAll,list,p.right,target);
list.remove(list.size()-1);
}
}
public boolean isRightPath(final List<Integer> list,final int target){
int sum = 0;
for(int x : list ){
sum+=x;
}
return sum == target;
}
二叉树的所有路径
public List<String> binaryTreePaths(TreeNode root) {
// write your code here
List<String> list = new ArrayList<String>();
if(root == null){
return list;
}
TreeNode p = root;
String temp = new String();
getAllPath(p,temp,list);
return list;
}
void getAllPath(TreeNode p,String temp, List<String> list){
if(temp.equals("")){//java中new的对象在堆内存中,用equals比较方法
temp += p.val;
}else{
temp += "->" + p.val;
}
if(p.left == null && p.right == null){
list.add(new String(temp));
return ;
}
if(p.left != null){
getAllPath(p.left,temp,list);
}
if(p.right != null){
getAllPath(p.right,temp,list);
}
}
排列
全排列 - 递归方法
比如数组为[1,2,3,4]
当第一位为1时,求2,3,4的所有可能
当第一位为2时,求1,3,4的所有可能
当第一位为3时,求1,2,3的所有可能
可以按照找规律方法,当第一位确定的时候,其实就是找剩下位置的全排列,可以通过递归的方法来递归求解,当第一位确定了之后,再通过递归的方法来确定剩下的位数的全排列结果。
public List<List<Integer>> permute(int[] nums) {
// write your code here
List<List<Integer>> ret = new ArrayList<List<Integer>>();
List<Integer> temp = new ArrayList<Integer>();
if(nums.length == 0){
ret.add(temp);
return ret ;
}
if(nums.length == 1){
temp.add(nums[0]);
ret.add(temp);
return ret ;
}
getAllSort(0,temp,ret,nums);;
return ret;
}
void getAllSort(int pos,List<Integer> temp,List<List<Integer>> ret,int[] nums){
if(temp.size()==nums.length){
ret.add(new ArrayList(temp));
return ;
}
for(int i= pos; i<nums.length;i++){
int tep = nums[i];//swap操作,第pos位6的可能
nums[i] = nums[pos];
nums[pos] = tep ;
temp.add(nums[pos]);
getAllSort(pos+1,new ArrayList(temp),ret,nums);
temp.remove(temp.size()-1);
int tep2 = nums[i];//换回来,返回到初始的状态
nums[i] = nums[pos];
nums[pos] = tep2 ;
}
}
上一个排列与下一个排列
笨点的方法就是先把给出的结果全排列出来,再再结果列表中查找上一个或者下一个排列的可能
上一个排列:从后往前查找第一个递增,即list.get(i)>list.get(i+1),再在 i 后查找到最大但同时小于list.get(i) 的元素(位于j处),将i,j元素相互交换,再将I位置以后的进行反转操作,就可以得到上一个队列
public List<Integer> previousPermuation(List<Integer> nums) {
// write your code here
if(nums.size()==0||nums.size()==1)
return nums;
List<Integer> ret = new ArrayList<Integer>();
int len = nums.size()-2;
for(;len>=0;len--){
if(nums.get(len)>nums.get( len+1)){
break;
}
}
return aboveSort(len,nums);
}
public List<Integer> aboveSort(int len ,List<Integer> list){
if(len<0){
//全部反转
Collections.reverse(list);
return list;
}else{
//部分反转,先交换两个数的位置,再将len后的数组反转
int pos = list.size()-1;
int max = Integer.MIN_VALUE;
int maxValuePos = list.size()-1;
for( ;pos>len;pos--){
if(list.get( pos )>max&&list.get(pos)<list.get(len)){
max = list.get( pos );
maxValuePos = pos;
}
}
Collections.swap( list,len,maxValuePos );
len++;
int size = list.size()-1;
int i=0;
while(len + i < size - i ){
Collections.swap(list,len+i,size -i );
i++;
}
return list;
}
}
下一个排列
与上一个排列相似,从后往前找第一个满足list.get(i)<list.get(i+1),再从后往前找到第一个比list.get(i)大的数(j),交换i,j,再将i之后的元素进行反转
public int[] nextPermutation(int[] nums) {
// write your code here
if(nums.length<=1){
return nums;
}
int size = nums.length - 1 ;
int pos = size-1;
for(;pos>=0;pos--){
if(nums[pos]<nums[pos+1]){
break ;
}
}
if(pos<0){
//全部反转
int begin = 0;
int count = 0;
while(begin+count<size-count){
int temp = nums[begin+count];
nums[begin+count] = nums[size-count];
nums[size-count] = temp;
count++;
}
return nums;
}else{
// find first bigger val
int firGre = size;
for(int i =size;i>=pos;i--){
if(nums[i]>nums[pos]){
firGre = i;
break;
}
}
//swap
int temp = nums[pos];
nums[pos] = nums[firGre];
nums[firGre] = temp;
//reverse
pos++;
int count = 0;
while(pos+count<size-count){
temp = nums[pos+count];
nums[pos+count] = nums[size-count];
nums[size-count] = temp;
count++;
}
return nums;
}
}
第K个排列
本来是想全排列或则进行n-1次的下一次下一个队列的操作,后来看网上的大佬们的神奇操作,找到了数学的规律。。
每一位上的数字为 num = k/(n-1)! ;
然后在list中数字删掉,数字不重复。
之后K减去(num-1)*(n-1)! , n也要减一:n-1
引用博客的地址:https://blog.csdn.net/qq_38310176/article/details/81227086
public String getPermutation(int n, int k) {
// write your code here
String result = "";
List<Integer> v = new ArrayList<Integer>();
for(int i=1;i<=n;i++) v.add(i);
int num = 0, f = 0;
for(int i=1;i<n;i++) {
k -= (num-1)*f;
f = Solution.Factorial(n-i);
num = (int)Math.ceil((double)k/f);
result += String.valueOf(v.get(num-1));
v.remove(num-1);
}
return result+v.get(0);
}
public static int Factorial(int n) {
while(n > 1) {
return n*Factorial(n-1);
}
return 1;
}
字符串置换
判断一个字符串是否可以通过位移来变换成另一个字符串
通过ASCLL码比较最后相加结果是否相同,或者按照字典排序,在比较两个字符串是否相等
public boolean Permutation(String A, String B) {
// write your code here
if(A == null && B == null){
return true;
}
char[] a = A.toCharArray();
char[] b = B.toCharArray();
if(a.length != b.length){
return false;
}
int aASC = 0;
int bASC = 0;
for(int i=0;i<a.length;i++){
aASC+=a[i];
bASC+=b[i];
}
if(aASC == bASC){
return true;
}
return false;
}
分治法
判断是否是平衡树
分别从左右两分支判断左右子树是否为平衡树,再比较左右两子树是否都为平衡树,思想类似二分法,分开查询,最后再判断结果并集
public boolean isBalanced(TreeNode root) {
// write your code here
if(root == null){
return true;
}
int leftDepth = maxDepth(root.left);
int rightDepth = maxDepth(root.right);
if(Math.abs(leftDepth-rightDepth)>1){
return false;
}else{
return isBalanced(root.left)&&isBalanced(root.right);
}
}
//查找当前节点的最大深度
int maxDepth(TreeNode root){
if(root == null){
return 0;
}
int left = maxDepth(root.left)+1;
int right = maxDepth(root.right)+1;
return left > right ? left : right;
}
二叉树的最大路径
这个问题用C++很简单,就是分治,左右两子树查找最大的路径,选出左右路径最大的那条,返回代表这节点最大的路径,最后比较左右节点最大路径相加和已有的路径相比。使用java就需要注意传值和传址的问题,基础数据类型都是传值(不含String),我这里使用是数组的方法解决
public int maxPathSum(TreeNode root) {
// write your code here
int[] sum =new int[1];
sum[0] = Integer.MIN_VALUE;
maxSum(root,sum);
return sum[0] ;
}
int maxSum(TreeNode root,int[] sum){
if(root == null){
return 0;
}
//左右子树的最大路径,0是可能不选这条子路径上的节点或者真的路径和就是0
int left = maxSum(root.left,sum);
int right = maxSum(root.right,sum);
sum[0] = Math.max(sum[0],Math.max(0,left)+Math.max(0,right)+root.val);
return Math.max(0,Math.max(left,right))+root.val;
}
是否查找二叉树
从左叉是递减的,右叉是递增的,且左子树节点都小于该节点,右子树都大于该节点。所以判断左子树和右子树不仅要判断是递减或递增,还要判断,左子树的所有节点都小于该父节点,右子树的所有节点都大于该父节点。
boolean firstNode=true; //判断左子树还是右子树
int lastVal = Integer.MAX_VALUE; //存放当前子树的父节点的值
public boolean isValidBST(TreeNode root) {
// write your code here
if(root == null){
return true;
}
if(!isValidBST(root.left)){
return false;
}
if(!firstNode && lastVal >= root.val){ //右子树值小于当前子树父节点的值
return false;
}
firstNode = false;
lastVal = root.val;
if(!isValidBST(root.right)){
return false;
}
return true;
}
合并K个排序的链表
多个两个链表合并的操作
public ListNode mergeKLists(List<ListNode> lists) {
// write your code here
if(lists.size()==0){
return null;
}
if(lists.size()==1){
return lists.get(0);
}
int size = lists.size();
while(size > 1){
int k = (size+1)/2;
for (int i = 0; i < size / 2; ++i) {
lists.set(i,mergr(lists.get(i), lists.get(i+k)));
}
size = k;
}
return lists.get(0);
}
ListNode mergr(ListNode l1,ListNode l2){
ListNode head = new ListNode(-1);
ListNode p = head;
while(l1!=null&&l2!=null){
if(l1.val<l2.val){
head.next = new ListNode(l1.val);
l1=l1.next;
}else{
head.next = new ListNode(l2.val);
l2=l2.next;
}
head = head.next;
}
while(l1 != null){
head.next = new ListNode(l1.val);
l1=l1.next;
head = head.next;
}
while(l2 != null){
head.next = new ListNode(l2.val);
l2=l2.next;
head = head.next;
}
return p.next;
}
回溯法
回溯法主要是返回上一步的状态,类似的全排列,子集等
子集
给出一个数组,由前一步返回到这一步时,将状态回滚
例如给出给出数组[1,2,3]
初始时Pos为0
temp [] [1] [1,2] [1,2,3] ,[1,3]
当pos 0执行完,temp此时清空 []
当pos =1
temp [2] ,[2,3]
当pos =2
temp [3]
此时得到所有的结果子集
public List<List<Integer>> subsets(int[] nums) {
// write your code here
List<List<Integer>> ret = new ArrayList<List<Integer>>();
List<Integer> temp = new ArrayList<Integer>();
if(nums.length == 0){
ret.add(temp);
return ret ;
}
Arrays.sort(nums);
getAllSonSort(0,nums,ret,temp);
return ret ;
}
void getAllSonSort(int pos, int[] nums, List<List<Integer>> ret, List<Integer> temp){
ret.add(new ArrayList(temp));
for(int i=pos;i<nums.length;i++){
temp.add(nums[i]);
getAllSonSort(i+1,nums,ret,temp);
temp.remove(temp.size()-1);
}
}
单词搜索
给出board =
["ABCE", "SFCS", "ADEE"]
word = "ABCCED", ->返回 true,word = "SEE",-> 返回 true,word = "ABCB", -> 返回 false.
一开始想到的方法就是暴力破解,从每个节点开始查,上下左右再去遍历得到结果,代码比较臃肿。
public class WordSearch {
public static void main(String args[]){
char[][] board = new char[][]{{'A','B','C','E'},
{'S','F','C','S'},
{'A','D','E','E'}};
String word = new String( "ABCCEE" );
if(exist( board,word )){
System.out.println( "true" );
}else{
System.out.println( "false" );
}
}
public static boolean exist(char[][] board,String word){
int height = board.length;
int weight = board[0].length;
String temp = new String();
if(word.length()==0){
return true;
}
for(int i=0;i<height;i++) {
for (int j = 0; j < weight; j++) {
temp = "";
//每次查询时,初始化访问路径
Boolean[][] visit = new Boolean[height][weight];//存放该节点是否访问过
for(int k=0;k<height;k++){
for(int l=0;l<weight;l++){
visit[k][l] = false;
}
}
//查询该节点为起点是否满足
if(mathWord(i,j,visit,board,word)){
return true;
}
}
}
return false;
}
//由某点开始是否可以得到这个单词
public static boolean mathWord(int cur,int row,Boolean[][] visit,char[][] board,String word){
if(word.length() == 0){
return true;
}
//越界条件
if(cur<0 || cur>=board.length || row<0 || row >= board[0].length) {
return false;
}
String ch = word.substring( 0,1 );
String bo = String.valueOf( board[cur][row] );
if((ch.equals( bo )) && (visit[cur][row] == false)){
visit[cur][row] = true;
String temp = new String( word.substring( 1 ) );
boolean res = mathWord( cur+1,row,visit,board,temp)||mathWord( cur-1,row,visit,board,temp)||
mathWord( cur,row+1,visit,board,temp)||mathWord( cur,row-1,visit,board,temp);
visit[cur][row] = false;
return res;
}
return false;
}
}
分割回文串
不改变字符串的顺序,将元素分割成为可以回文的字符数组
public class BackString {
public static void main(String args[]){
String str = new String("aabb");
backString(str );
int i=0;
}
public static List<List<String>> backString(String str){
List<List<String>> ret = new ArrayList<List<String>>( );
List<String> list =new ArrayList<String>( );
if(str.length()<=1){
list.add( str );
ret.add( list );
return ret;
}
getAllBackStr(0,str,list,ret);
return ret ;
}
public static void getAllBackStr(int pos,String str,List<String> list,List<List<String>> ret){
if(pos >= str.length()){
ret.add( new ArrayList<String>( list ) );
return ;
}
for(int i=pos;i<str.length();i++){
String temp = new String( str.substring( pos,i+1 ) );//获取相应的字符串
if(!isBackStr( temp )){
continue;
}
list.add( temp );
getAllBackStr(i+1,str,list,ret);
list.remove( list.size()-1 );
}
}
public static boolean isBackStr(String stri){
int len = stri.length();
if(stri==null || stri.equals( "" )){
return false;
}
if(len <= 1 ){
return true;
}
for(int i=0;i<=len/2-1;i++){
char a = stri.charAt( i );
char b = stri.charAt( len-i-1 );
if(a != b){
return false;
}
}
return true;
}
}
动态规划
经典问题就是0,1背包问题
动态规划的主要找出上一步和下一步的关系。
经典的背包问题为: 如果有4个物品[2, 3, 5, 7]
如果背包的大小为11,可以选择[2, 3, 5]装入背包,最多可以装满10的空间。
如果背包的大小为12,可以选择[2, 3, 7]装入背包,最多可以装满12的空间。
函数需要返回最多能装满的空间大小。
假设创建二维数组 dp[a.size] [m] 用来处理上一部与下一步的关系
初始化dp[0][ ] 为0
dp[i] [j]为能否放入第I个物体,其中j为此时的容量大小
当j>a[i]
满足关系 dp[i][j] = Math.max(dp[i-1][j] , dp[i-1][j-a[i]] +a[i]);
不然就直接继承上一种
dp[i][j] = dp[i-1][j]
这种方法比较容易理解,但是在lintcode中会报limit memory.使用的空间还是太多了。
public class PackageProblem {
public static void main(String args[]){
int[] a = {2,3,5,7};
int count = 12;
int num = getMaxWight(a,count);
int i=0;
}
public static int getMaxWight(int[] a,int count){
int len = a.length;
int[][] dp = new int[len][count+1];
//初始化动态规划的结果集
for(int i=0;i<len;i++){
for(int j=0;j<count+1;j++){
dp[i][j] = 0;
}
}
//第一个物体放入的可能结果集
for(int i=0;i<=count;i++){
if(i>=a[0]){
dp[0][i] = a[0];
}
}
for(int i=1;i<len;i++){
for(int j =1;j<=count;j++){
if(j>a[i]){//当前的内存能够放入第i个物体
dp[i][j] = Math.max( dp[i-1][j],dp[i-1][j-a[i]]+a[i] );//比较放入第i个物体和不放入第i个物体的最大值
}else{
dp[i][j] = dp[i-1][j];
}
}
}
return dp[len-1][count];
}
}
N皇后问题
皇后之间不能再同一条线上,及不能在45‘,135,斜线上有皇后存在。
判断条件可以为
创建List<Integer> 存放每行皇后的位置。
temp.get(i) == c || Math.abs(row-i) == Math.abs( c-temp.get(i))
public class NumQueenProblem {
public static void main(String args[]){
int n = 4;
solveNQueens( n );
}
public static List<List<String>> solveNQueens(int n){
List<List<String>> solutions = new ArrayList<List<String>>( );
List<Integer> temp = new ArrayList<Integer>( );//记录当前行的位置信息
for(int i=0;i<n;i++){
temp.add( -1 );
}
getAllSolution(solutions,temp,n,0);
return solutions;
}
public static void getAllSolution(List<List<String>> solutions,List<Integer> temp,int n,int row){
if(row >= n){
List<String> solution = new ArrayList<String>( getResult( temp ) );
solutions.add( solution );
}else {
for (int i = 0; i < n; i++) {
if(isValid( temp,row,i )){
temp.set( row,i );
getAllSolution(solutions,temp,n,row+1);
}
}
}
}
//判断该点是否满足N皇后规则,不在一条线上且不相邻
public static boolean isValid(List<Integer> temp , int row, int c){
if( temp.size() == 0 ){
return true;
}
for(int i=0;i<row;i++){
if(temp.get(i) == c || Math.abs(row-i) == Math.abs( c-temp.get(i) )){
return false ;
}
}
return true;
}
//将链表转换为字符串链表
public static List<String> getResult(List<Integer> temp){
if(temp.size() == 0) {
return new ArrayList<String>();
}
List<String > ret = new ArrayList<String>( );
int len = temp.size();
for(int i=0;i<len;i++){
String tep = new String();
//第i行的字符串
for(int k=0;k<len;k++){
if(k == temp.get( i )){
tep+="Q";
}else{
tep+=".";
}
}
ret.add( tep );
}
return ret;
}
}
N皇后问题二
还是要注意java中传值和传址的问题,我怎么还在猥琐用数组呢???,要抽时间写一篇关于传值和传址的博客了
public class Solution {
/**
* @param n: The number of queens.
* @return: The total number of distinct solutions.
*/
public int totalNQueens(int n) {
// write your code here
int[] solutions = new int[1];
solutions[0]=0;
List<Integer> temp = new ArrayList<Integer>( );//记录当前行的位置信息
for(int i=0;i<n;i++){
temp.add( -1 );
}
getAllSolution(solutions,temp,n,0);
return solutions[0];
}
public void getAllSolution(int[] solutions,List<Integer> temp,int n,int row){
if(row >= n){
solutions[0]++;
}else {
for (int i = 0; i < n; i++) {
if(isValid( temp,row,i )){
temp.set( row,i );
getAllSolution(solutions,temp,n,row+1);
}
}
}
}
public boolean isValid(List<Integer> temp , int row, int c){
if( temp.size() == 0 ){
return true;
}
for(int i=0;i<row;i++){
if(temp.get(i) == c || Math.abs(row-i) == Math.abs( c-temp.get(i) )){
return false ;
}
}
return true;
}
}
排序算法
快速排序(第K大元素)
public class Solution {
/**
* @param n: An integer
* @param nums: An array
* @return: the Kth largest element
*/
public int kthLargestElement(int n, int[] nums) {
// write your code here
if(n > nums.length){
return 0;
}
int start=0;
int end=nums.length-1;
int index=partition(nums, 0, nums.length-1);
while(index != nums.length-n){
if(index > nums.length-n){
index=partition(nums, start, index-1);
}else{
index=partition(nums, index+1, end);
}
}
return nums[index];
}
private int partition(int []nums,int start,int end){
int left=start;
int right=end;
int pivot=nums[start];
while(left<right){
while(left<right&&nums[right]>=pivot)
right--;
if(left<right){
nums[left]=nums[right];
left++;
}
while(left<right&&nums[left]<pivot)
left++;
if(left<right){
nums[right]=nums[left];
right--;
}
}
nums[left]=pivot;
return left;
}
}