如何判断链表有环
/**
* 判断是否有环
* @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];
}
寻找缺失的整数