算法留存

来源:互联网 发布:韩国和中国知乎 编辑:程序博客网 时间:2024/05/17 03:16

1.堆排序

import java.util.Arrays;


public class HeapSort {


public static void main(String[] args) {
int[] array = new int[] { 49, 38, 65, 97, 76, 13, 27, 49, 78, 34, 12,
64, 5, 4, 62, 99, 98, 54, 56, 17, 18, 23, 34, 15, 35, 25, 53,
51 };
buildMaxHeap(array);
for(int i=array.length-1;i>0;i--){
swap(array, 0, i);
adjustHeap(array, 0, i-1);
}
System.out.println(Arrays.toString(array));
}

public static void buildMaxHeap(int[] array){
for(int i=(array.length-2)/2;i>=0;i--){
adjustHeap(array,i,array.length-1);
}
}

public static void adjustHeap(int[]array,int index,int lastIndex){
while(index*2+1<=lastIndex){
int bigger=2*index+1;
if(bigger+1<=lastIndex&&array[bigger+1]>array[bigger]){
bigger++;
}
if(array[index]<array[bigger]){
swap(array, index, bigger);
index=bigger;
}else {
break;
}
}
}

public static void swap(int[]array,int i,int j){
int temp=array[j];
array[j]=array[i];
array[i]=temp;
}
}


2.归并排序

import java.util.Arrays;


public class MergeSort {


public static void main(String[] args) {
int[] array = new int[] { 49, 38, 65, 97, 76, 13, 27, 49, 78, 34, 12,
64, 5, 4, 62, 99, 98, 54, 56, 17, 18, 23, 34, 15, 35, 25, 53,
51 };
mergeSort(array, 0, array.length-1);
System.out.println(Arrays.toString(array));
}

public static void mergeSort(int[] array,int left,int right){
if(left<right){
int mid=(left+right)/2;
mergeSort(array, left, mid);
mergeSort(array, mid+1, right);
merge(array,left,mid,right);
}
}

public static void merge(int[]array,int left,int center,int right){
int[] temp=new int[array.length];
int rp=center+1;
int tempIndex=left;
int copyIndex=left;
while(left<=center&&rp<=right){
if(array[left]<=array[rp]){
temp[tempIndex++]=array[left++];
}else {
temp[tempIndex++]=array[rp++];
}
}
while(left<=center){
temp[tempIndex++]=array[left++];
}
while(rp<=right){
temp[tempIndex++]=array[rp++];
}

while(copyIndex<=right){
array[copyIndex]=temp[copyIndex++];
}
}
}


3.import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;


/*
 * 构造邻接矩阵,并用邻接矩阵解决有向图的连通性问题
 * 问题描述:给定两颗钻石的编号g1,g2,编号从1开始,同时给定关系数组vector,其中元素为一些二元组,
 * 第一个元素为一次比较中较重的钻石的编号,第二个元素为较轻的钻石的编号。最后给定之前的比较次数n。
 * 请返回这两颗钻石的关系,若g1更重返回1,g2更重返回-1,无法判断返回0。输入数据保证合法,不会有矛盾情况出现。
 * 
 * 测试用例:2,3,[[1,2],[2,4],[1,3],[4,3]],4
 * 返回: 1
 */
public class DigraphConnectivity {
private boolean flag=false;
public static void main(String[] args) {
DigraphConnectivity di=new DigraphConnectivity();
di.scanner();
}

public void scanner(){
Scanner in=new Scanner(System.in);
while(in.hasNextInt()){
HashMap<Integer,ArrayList<Integer>> map=new HashMap();
int g1=in.nextInt();
int g2=in.nextInt();
int n=in.nextInt();
for(int i=0;i<n;i++){
int key=in.nextInt();
int value=in.nextInt();
if(map.containsKey(key)){
map.get(key).add(value);
}else {
ArrayList<Integer> list=new ArrayList<Integer>();
list.add(value);
map.put(key, list);
}
}
isConnectivity(g1, g2, map);
if(flag){
System.out.println(1);
}
isConnectivity(g2, g1, map);
if(flag){
System.out.println(-1);
}
System.out.println(0);
}
}

//用邻接矩阵构建有向图的过程
public void isConnectivity(int g1,int g2,HashMap<Integer, ArrayList<Integer>> map){
if(!map.containsKey(g1)){
flag=false;
}else {
ArrayList<Integer> list=map.get(g1);
for(int value:list){
if(value==g2){
flag=true;
return;
}else {
isConnectivity(value, g2, map);
}
}
}
}
}


4./*
 * 最大子数组和
 * 
 * 题目描述:在一维数组中,求出连续子数组的最大和。如果数组中全是整数,那么最大和为所有元素之和,
 * 那么存在负数呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。
 * 
 * 思路:
 * 1. 首先,需要定义一个变量currentSum,用for循环来记录前i项的和,currentSum每次都会更改,
 * 如果currentSum的值小于0,再往后加只有减小最大和,所以需要将array[i+1]项的值重新赋值给currentSum。
 * 2. 需要定义一个最大值max,每次改变currentSum的值时,我们都需要将max和currentSum进行比较,
 * 如果currentSum大于max,我们则将currentSum的值赋值给max。
 */


public class MaxArraySum {
public static void main(String[] args) {
int[] array = new int[] { 6, -3, -2, 7, -15, 1, 2, 2 };
System.out.println(maxArraySum(array));
}

public static int maxArraySum(int[] array){
if(array.length<=0||array==null){
return 0;
}
int currentSum=0;
int max=0;
for(int i=0;i<array.length;i++){
if(currentSum<=0){
currentSum=array[i];
}else {
currentSum+=array[i];
}
if(currentSum>max){
max=currentSum;
}
}
return max;
}
}


5.import java.util.Scanner;


/*
 * 并查集解决(无向图)连通性
 * 并查集的3种操作:
 * (1)init()把每一个元素初始化为一个集合,初始化后的每一个元素的父节点是它本身
 * (2)Find_Set(int x)查找一个元素所在的集合,关键在于寻找这个元素所在集合的祖先
 * (3)Union(int x, int y)合并x和y所在的集合,一个集合的祖先指向另一个集合的祖先
 * 
 * 先输入10个人(编号从1-10)及7组亲戚关系,然后输入3组数据,问这三组数据是不是亲戚关系?
 * 输入 :(10 7)(2 4)(5 7)(1 3)(8 9)(1 2)(5 6)(2 3) 3 (3 4)(7 10)(8 9)
 * 输出: Yes No Yes
 */
public class UnionFindUndigraph {
int[] father;
public void scanner(){
Scanner in=new Scanner(System.in);
int n=in.nextInt();
int m=in.nextInt();
father=new int[n+1];
init();
for(int i=0;i<m;i++){
int a=in.nextInt();
int b=in.nextInt();
union(a, b);
}
int p=in.nextInt();
for(int i=0;i<p;i++){
int a=in.nextInt();
int b=in.nextInt();
if(find(a)==find(b)){
System.out.println("yes");
}else {
System.out.println("no");
}
}
}

public void init(){
for(int i=0;i<father.length;i++){
father[i]=i;
}
}

public int find(int x){
if(x!=father[x]){
father[x]=find(father[x]);
}
return father[x];
}

public void union(int x,int y){
int f1=find(x);
int f2=find(y);
if(f1!=f2){
father[f1]=f2;
}
}

public static void main(String[] args) {
UnionFindUndigraph u=new UnionFindUndigraph();
u.scanner();
}
}


6.最长公共子串

public class CommonSubstring {
public static void main(String[] args) {
commonSubstring("123456abcd567", "234dddabc45678");
}


public static void commonSubstring(String s1,String s2){
int longest=0;
int len1=s1.length();
int len2=s2.length();
int[]max=new int [len1];
int[][]matrix=new int[len1+1][len2+1];
for(int i=1;i<=len1;i++){
for(int j=1;j<=len2;j++){
if(s1.charAt(i-1)==s2.charAt(j-1)){
matrix[i][j]=matrix[i-1][j-1]+1;
if(matrix[i][j]>longest){
longest=matrix[i][j];
for(int k=0;k<len1;k++){
max[k]=0;
}
max[i-1]=1;
}else if (longest==matrix[i][j]) {
max[i-1]=1;
}
}
}
}

for(int k=0;k<len1;k++){
if(max[k]==1){
System.out.println(s1.substring(k-longest+1, k+1));
}
}
}
}
 

7.最长公共子序列

**
 * 最长公共子序列
 * 状态改变函数:
 * num[i][j] = 0   (m==0 , || n==0)
 * num[i][j] = 1 + num(m-1,n-1)  (a[m] == b[n])
 * num[i][j] = max(LCS(m,n-1),LCS(m-1,n))  (a[m] != b[n])
 * @author samsung
 *
 */


public class CommonSubsequence {
public static void main(String[] args) {
System.out.println(commonSubsequece("a1b2c3", "1a1wbz2c123a1b2c123"));
}


public static String commonSubsequece(String s1,String s2){
StringBuilder sb=new StringBuilder();
int length1=s1.length();
int length2=s2.length();
int[][] matrix=new int[length1+1][length2+1];
for(int i=1;i<=length1;i++){
for(int j=1;j<=length2;j++){
if(s1.charAt(i-1)==s2.charAt(j-1)){
matrix[i][j]=matrix[i-1][j-1]+1;
}else if (matrix[i-1][j]>matrix[i][j-1]) {
matrix[i][j]=matrix[i-1][j];
}else {
matrix[i][j]=matrix[i][j-1];
}
}
}
char[] ch=new char[length1];
int i=length1;
int j=length2;
int k=0;
while(i>0&&j>0){
if(s1.charAt(i-1)==s2.charAt(j-1)){
ch[k++]=s1.charAt(i-1);
i--;
j--;
}else if (matrix[i-1][j]>=matrix[i][j-1]) {
i--;
}else {
j--;
}
}

for(int p=k-1;p>=0;p--){
sb.append(ch[p]);
}
return sb.toString();
}
}


8.

import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap;


/**
 * 最大回文子串的求法
 * @author samsung
 *
 */
public class LongestPalindromic {


public static void main(String[] args) {
String s="babcbabcbaccba";
System.out.println(violenceSearch(s));
System.out.println(dynamic(s));
}
/**
* 暴力搜索法
* @param s
* @return
*/
public static String violenceSearch(String s){
int longest=0;
String longestPalindromic=null;
int n=s.length();
for(int i=0;i<n-2;i++){
for(int j=i+1;j<n;j++){
int len=j-i;
String sub=s.substring(i, j+1);
if(isPalindromic(sub)){
if(len>longest){
longest=len;
longestPalindromic=sub;
}
}
}
}
return longestPalindromic;
}

public static boolean isPalindromic(String s){
int i=0;
int j=s.length()-1;
while(i<j){
if(s.charAt(i)!=s.charAt(j)){
return false;
}
i++;
j--;
}
return true;
}

/**
* 动态规划法
* 要点一、注意最后两个for循环的边界len是循环子串长度所以到n,
* i不能超过边界,所以是n-len保证检查到最后len个
* 要点二、假设dp[ i ][ j ]的值为true,表示字符串s中下标从 i 到 j 的字符组成的子串是回文串。
* 那么:dp[ i ][ j ] = dp[ i + 1][ j - 1] && s[ i ] == s[ j ]。
* @return
*/
public static String dynamic(String s){
int n=s.length();
int max=0;
String result=null;
int[][] matrix=new int[n][n];
for(int i=0;i<n;i++){
matrix[i][i]=1;
}
for(int i=0;i<=n-2;i++){
if(s.charAt(i)==s.charAt(i+1)){
matrix[i][i+1]=1;
max=2;
result=s.substring(i, i+2);
}
}
for(int len=3;len<=n;len++){
for(int i=0;i<=n-len;i++){
int j=i+len-1;
if(s.charAt(i)==s.charAt(j)&&matrix[i+1][j-1]==1){
matrix[i][j]=1;
if(len>max){
max=len;
result=s.substring(i, j+1);
}
}
}
}
return result;
}
}

0 0
原创粉丝点击