漫画算法第五章

如何判断链表有环

/**
 * 判断是否有环
 * @param head 链表头节点
 */
 public static Boolean isCycle(Node head){
 	Node fast = head;
 	Node slow = head;
 	while(fast!=null&&fast.next!=null){
 		fast = fast.next.next;
 		slow = slow.next;
 		if(fast==slow){
 			return true;
		}
 	}
 	return false;
 }
 

扩展问题1:
如果有环,如何求出环的长度?

/**
 * 求出环的长度
 * @param head 链表头节点
 */
 public static int isCycle(Node head){
 	int len = 0;
 	Node fast = head;
 	Node slow = head;
 	while(fast!=null&&fast.next!=null){
 		fast = fast.next.next;
 		slow = slow.next;
 		if(fast==slow){
 			do{
 				slow = slow.next;
 				len++;
 			}while(fast!=slow);
 			break;
		}
 	}
 	return len;
 }
 

扩展问题1:
如果有环,如何求出入环节点?

/**
 * 求出入环节点
 * @param head 链表头节点
 */
 public static Node isCycle(Node head){
 	int len = 0;
 	Node fast = head;
 	Node slow = head;
 	while(fast!=null&&fast.next!=null){
 		fast = fast.next.next;
 		slow = slow.next;
 		if(fast==slow){
 			fast = head;
 			while(fast!=slow){
 				fast = fast.next;
 				slow = slow.next;
 			}
 			break;
		}
 	}
 	return fast;
 }
 

如何求出最大公约数

方法一:辗转相除法
不过有一个问题,当两个整数较大时,做a%b取模运算的性能会比较差

public static int gcd(int a, int b){
	int small = a>b?b:a;
	int big = a>b?a:b;
	
	return (big%small==0)?:small:gcd(small,big%small);
}

方法二:更相减损法
运算次数肯定远大于辗转相除法的取模方式

public static int gcd(int a, int b){
	int small = a>b?b:a;
	int big = a>b?a:b;
	
	return (big==small)?:small:gcd(small,big-small);
}

在这里插入图片描述

public static int gcd(int a, int b){
	if( a==b ) return a;
	if( (a&1)==0&&(b&1)==0 ){
		return gcd(a>>1,b>>1)<<1;
	}
	else if((a&1)==0){
		return gcd(a>>1,b);
	}
	else if((b&1)==0){
		return gcd(a,b>>1);
	}else{
		int small = a>b?b:a;
		int big = a>b?a:b;
		return gcd(small,(big-small)>>1);
	}
}

如何判断一个数是否为2的整数幂

public boolean inPowerOf2(int num){
return (num&(num-1)==0);
}

无序数组排序后的最大相邻差

计数排序在这里插入图片描述在这里插入图片描述
桶排序
在这里插入图片描述
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210715175528678.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2N5YW5fY29sb3I=,size_16,color_FFFFFF,t_70

/**
* 桶
*/
private static class Bucket{
	Integer min;
	Integer max;
}
public static int getMaxSortedDistance(int[] array){
	//1.得到数列的最大值和最小值
	int max = array[0];
	int min = array[0];
	for(int num:array){
		min = Math.min(num,min);
		max = Math.max(num,max);
	}
	int d = max-min;
	if(d==0) return 0
	//2.初始化桶
	int bucktNum = array.length;
	Bucket[] buckets = new Bucket[bucktNum ];
	for(int i=0; i<bucktNum ;i++){
		buckets[i] = new Bucket();
	}
	//3.遍历原始数组,确定每个桶的最大最小值
	for(int num:array){
		//确定数组元素所归属的桶下标
		int index = (array[i]-min)*(bucketNum-1)/d;
		if(buckets[index].min==null||buckets[index].min>num){
			buckets[index].min = num;
		}
		if(buckets[index].max==null||buckets[index].max<num){
			buckets[index].max= num;
		}
		
	}

	//4.遍历桶,找到最大差值;
		int maxDistance = 0;
		leftmax = buckets[0].max;
		for(int i=1; i<buckets.length; i++){
			if(buckets[i].min == null){
				continue;
			}
			if(buckets[i].min-leftmax>maxDistance ){
				maxDistance = buckets[i].min-leftmax;
			}
			leftmax = buckets[i].max;
		}
		return maxDistance;

	
}

寻找全排列的下一个数

在这里插入图片描述
在这里插入图片描述

删去k个数字后的最小值

单调栈 Integer.parseInt(String str) String.valueOf(int i)
在这里插入图片描述在这里插入图片描述
在这里插入图片描述

如何实现大整数相加

public static String addBigNum(String str1, String str2){
	int m = str1.length();
	int n = str2.length();
	char[] ret = new char[Math.max(m,n)];
	int index = ret.length;
	int cp = 0;
	while(index>0){
		int a = (m>0)?str1.charAt(--m)-'0':0;
		int b = (n>0)?str2.charAt(--n)-'0':0;
		int sum= a+b+cp;
		cp = sum/10;
		ret[--index] = (char)(sum%10+'0');
	}
	return cp==1?"1"+new String(ret):new String(ret);
	
}

求解金矿问题

很久以前,有一位国王拥有5座近况,每座金矿的黄金储量不同,需要参与挖掘的工人人数不同
在这里插入图片描述
动态规划 - 背包问题


/** 求最多的黄金
*  @param w 工人数量
*  @param p 金矿开采所需工人数量
*  @param g 金矿储量
*/
public static getBestGoldMining(int w, int[] p, int[] g){
	int m = g.length;
	int[][] dp = new int[m][w+1];
	//初始化
	if(p[0]<=w){
		for(int i= p[0]; i<=w; i++){
			dp[0][j] = g[0];
		}
	}

	for(int i=1; i<m; i++){
		for(int j=1; j<w+1; j++){
			dp[i][j] = dp[i-1][j];
			if(j-p[i]>0){
				dp[i][j] = Math.math(g[i] + dp[i-1][j-p[i]], dp[i][j]);
			}		
		}
	}

	return dp[m-1][w];
}

寻找缺失的整数

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值