常用算法汇总

举报
SHQ5785 发表于 2022/07/16 09:51:54 2022/07/16
【摘要】 快速排序注:若排序是有序的,采用快排,则退化为冒泡排序。解决这个问题,采用两个选取基准的方法:(1)随机选取基数(在这个区间内随机取一个数)出现的恶劣情况是整个数组全相等,还是退化为冒泡排序(2)三数取中法把待排序列分成等长的子序列,最佳的是取中间数为基准举例:待排序序列为:8 1 4 9 6 3 5 2 7 0左边为:8,右边为0,中间为6.我们这里取三个数排序后,中间那个数作为枢轴,则...

快速排序

  • 注:若排序是有序的,采用快排,则退化为冒泡排序。

解决这个问题,采用两个选取基准的方法:
(1)随机选取基数(在这个区间内随机取一个数)
出现的恶劣情况是整个数组全相等,还是退化为冒泡排序
(2)三数取中法
把待排序列分成等长的子序列,最佳的是取中间数为基准
举例:待排序序列为:8 1 4 9 6 3 5 2 7 0
左边为:8,右边为0,中间为6.
我们这里取三个数排序后,中间那个数作为枢轴,则枢轴为6

四种优化方式:

  • 优化方式1:插排
    当待排序序列的长度分割到一定大小后(如子序列长度小于10),使用插入排序
  • 优化方式2:聚集相等元素
  • 优化方式3:采用尾递归
  • 优化方式4:采用并行或多线程处理子序列

堆排序

全排列

/**
	 * 字符串的排列:(考察的知识点就是全排列)
	 * 输入字符: a b c
	 * 输出字符:abc ,acb,bac,bca,cab,cba
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc=new Scanner(System.in);
		while(sc.hasNext()){
			String str=sc.next();
			ArrayList<String> re=Permutation(str);
			for(String s:re){
				System.out.println(s);
			}
		}

	}
	public static ArrayList<String> Permutation(String str) {
	     ArrayList<String> re=new ArrayList<String>();
	     if(str==null||str.length()==0){
	    	 return re;
	     }
			HashSet<String> set=new HashSet<String>();
			fun(set,str.toCharArray(),0);
			re.addAll(set);//将出现的字符串保存在list集合中
			Collections.sort(re);
			return re;
			
		}
	static void  fun(HashSet<String> re,char[] str, int k){
		if(k==str.length){
			re.add(new String(str));
			return;
		}
		for(int i=k;i<str.length;i++){//在for循环中,第一次初始化,然后判断,执行for循环体。执行完后i+1,在判断(初始化只执行一次)
			swap(str,i,k);
			fun(re,str,k+1);
			swap(str,i,k);//防止元素的重复,进行复原
			}
}
	//将数组中的两个数进行交换
	static void   swap(char[] str,int i,int j){
		if(i!=j){//相同就不用交换了
			char t=str[i];
			str[i]=str[j];
			str[j]=t;
		}
	}    
   }

二进制数中1的个数(用与运算)

static int  NumberOf3(int n) {
		int count=0;
		while(n!=0){//整数不为0,必有1
			++count;
			n=n&(n-1);
			
		}
		return count;
	}

反转二叉树(就是二叉树的镜像)

public void Mirror(TreeNode root) {
	 if(root==null) {//为空结点
  	   return;
     }
     if(root.left==null&&root.right==null){//表明该结点是叶子节点或只是根为的节点
  	   return;
     }
     //交换当前节点的左右子树
     TreeNode temp;
     temp=root.left;
     root.left=root.right;
     root.right=temp;
     if(root.left!=null){
  	   Mirror(root.left);
     }
     if(root.right!=null){
  	   Mirror(root.right);
     }
	}

通过前序、中序,重建二叉树

/**
	 * 解题的步骤:
	 * 1:递归的结束条件,只有到叶子节点,递归才结束(preStart==preEnd&&inStart==inEnd)
	 * 2:在中序中找到根,通过根算出左子树的长度,右子树的长度(左右子树各有多少个节点)
	 * 3:通过左子树的长度,算出前序左子树的起始节点(preStart+1,preStart+leftTree),中序左子树的起始节点(inStart,root-1),递归前提条件是leftLength>0(若为0,那就是叶子节点了)
	 * 4:同上算出右子树的递归
	 */
    public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
    	if(pre==null||in==null){//只要一个为空,另一个必为
    		return null;
    	}
    	TreeNode root=binaryTree(pre,in,0,pre.length-1,0,in.length-1);
    	return root;
    }
    public TreeNode binaryTree(int[] pre,int[] in,int preStart,int preEnd,int inStart,int inEnd){
    	//构造一个结点
    	TreeNode node=new TreeNode(pre[preStart]);
    	node.left=null;
    	node.right=null;
    	//现在要想想递归的结束条件是什么,preStart=preEnd和inStart=inEnd,表明这是一个叶子节点
    	if(preStart==preEnd&&inStart==inEnd){
    		return node;
    	}
    	//现在要找出根节点
    	int root=0;
    	//肯定在in数组中找了
    	for(int i=inStart;i<in.length;i++){
    		if(pre[preStart]==in[i]){
    			root=i;
    			break;
    		}
    	}
    	//找到根节点,就得算出左右子树的长度(肯定是通过in数组)
    	int leftTree=root-inStart;//要去掉根节点即第一个节点
    	int rightTree=inEnd-root;
    	if(leftTree>0){
    		node.left=binaryTree(pre,in,preStart+1,preStart+leftTree,inStart,root-1);
    	}
    	if(rightTree>0){
    		node.right=binaryTree(pre, in, preStart+leftTree+1, preEnd, root+1, inEnd);
    	}
    	
    	
    	return node;
    }
}

动态规划

  动态规划算法通常基于一个递推公式及一个或多个初始状态。当前子问题的解决由上一次子问题的解推出。

贪心算法

  每次选最大的,然后选择第二大的,在选第三大的,……,直到满足条件后结束或到最后也不能满足条件结束。

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。