单独开一个记录碰到的算法
选择问题
一组N个数确定其中第k个最大者
解法一
将这N个数读进数组,以递减的顺序排序,返回位置k上的元素
解法二
先把前k个元素读进数组,以递减的顺序排序,然后再逐个读入剩下的元素,如果比第k个元素小则忽略,比第k个元素大则放入数组的正确位置,同时将原来的第k个元素挤出数组
解法三
学习中,未完待续……
字符的排列
使用permute,显示字符的所有排列
解法一
public class Permute {
public static void main(String[] args)
{
Permute p = new Permute();
p.permute("abcd");
}
public void permute(String str) {
char[] chars = str.toCharArray();
permute(chars, 0, str.length()-1);
}
private void swap(char[] str, int a, int b) {
if (a == b) {
return;
}
char tempChar = str[a];
str[a] = str[b];
str[b] = tempChar;
}
private void permute(char[] str, int low, int high) {
if(low == high){
System.out.println(str);
return;
}
for(int i = low; i <= high; i++){
swap(str, low, i);
permute(str, low+1, high);
swap(str, i, low);
}
}
}
最大序列和
给定序列,求序列和的最大值
解法一
穷举尝试所有可能
public static int maxSubSum1(int [] a)
{
int maxSum = 0;
for(int i = 0; i < a.length; i++)
for(int j = i; i < a.length; j++)
{
int thisSum = 0;
for(int k = i; k <= j; k++)
thisSum += a[k];
if(thisSum > maxSum)
maxSum = thisSum;
}
return maxSum;
}
算法复杂度为O(N^3)
解法二
优化后的解法一
public static int maxSubSum1(int [] a)
{
int maxSum = 0;
for(int i = 0; i < a.length; i++)
{
int thisSum = 0;
for(int j = i; i < a.length; j++)
{
thisSum += a[j];
if(thisSum > maxSum)
maxSum = thisSum;
}
}
return maxSum;
}
算法复杂度为O(N^2)
解法三
递归分治,将问题分为子问题,然后递归求解。
最大序列可能在三处出现,整个出现在左半部,整个出现在右半部,或者跨越输入数据的中部,此时的最大和为左半部最大和加上右半部最大和。
private static int maxSumRec(int [] a, int left, int right)
{
if(left == right)
if(a[left] > 0)
return a[left];
else
return 0;
int center = (left + right) / 2;
int maxLeftSum = maxSumRec(a, left, center);
int maxRightSum = maxSumRec(a, center + 1, right);
int maxLeftBorderSum = 0, leftBorderSum = 0;
for(int i = center; i >= left; i--)
{
leftBorderSum += a[i];
if(leftBorderSum > maxLeftBorderSum)
maxLeftBorderSum = leftBorderSum;
}
int maxRightBorderSum = 0, rightBorderSum = 0;
for(int i = center + 1; i <= right; i++)
{
rightBorderSum += a[i];
if(rightBorderSum > maxRightBorderSum)
maxRightBorderSum = rightBorderSum;
}
return max3(maxLeftSum, maxRightSum, maxLeftBorderSum + maxRightBorderSum);
}
public static int maxSubSum3(int [] a)
{
return maxSumRec(a, 0, a.length - 1);
}
算法复杂度为O(Nlog(N))
解法四
public static int maxSubSum4(int [] a)
{
int maxSum = 0, thisSum = 0;
for(int j = 0; j < a.length; j++)
{
thisSum += a[j];
if(thisSum > maxSum)
maxSum = thisSum;
else if(thisSum < 0)
thisSum = 0;
}
return maxSum;
}
算法复杂度为O(N)
最小序列和
给定序列,求序列和的最小值
解法一
public static int minSubSum4(int [] a)
{
int minSum = 0, thisSum = 0;
for(int i = 0; i < a.length; i++)
{
thisSum += a[i];
if(thisSum < minSum)
minSum = thisSum;
else if(thisSum > 0)
thisSum = 0;
}
return minSum;
}
算法复杂度为O(N)
最小正子序列和
给定序列,求序列和的最小正值和
解法一
for(int i = 0; i != N; i++)
{
thisSum = 0;
for(int j = i; j != N; j++)
{
thisSum += A[j];
if(minSum > thisSum && thisSum > 0)
minSum = thisSum;
}
}
算法复杂度为O(N^2)
折半查找
public static <AnyType extends Comparable<? super AnyType>> int binarySearch(AnyType [] a, AnyType x)
{
int low = 0, high = a.length - 1;
while(low <= high)
{
int mid = (low + high) / 2;
if(a[mid].compareTo(x) < 0)
low = mid + 1;
else if(a[mid].compareTo(x) > 0)
high = mid - 1;
else
return mid;
}
return NOT_FOUND;
}
算法复杂度为O(log(N))
欧几里德算法
求两个整数的最大公因数
public static long gcd(long m, long n)
{
while(n != 0)
{
long rem = m % n;
m = n;
n = rem;
}
return m;
}
幂运算
public static long pow(long x, int n)
{
if(n == 0)
return 1;
if(n == 1)
return x;
if(isEven(n))
return pow(x * x, n / 2);
else
return pow(x * x, n / 2) * x;
}