【Java基础总结】-算法题总结

常见数据结构和算法编程题

1.二叉树的深度

public class Solution {
    public int TreeDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        return Math.max(TreeDepth(root.left), TreeDepth(root.right)) + 1;
    }
}

2.判断平衡二叉树

public class Solution {
    public boolean IsBalanced_Solution(TreeNode root) {
        if (root == null)
            return true;

        if (Math.abs(TreeDepth(root.left) - TreeDepth(root.right)) > 1)
            return false;

        return IsBalanced_Solution(root.left) && IsBalanced_Solution(root.right);

    }
    //计算二叉树的深度
    public int TreeDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        return Math.max(TreeDepth(root.left), TreeDepth(root.right)) + 1;
    }
}

3.排序算法总结

排序类别排序名称 (时间复杂度,空间复杂度,排序是否稳定)
交换类排序冒泡排序 (n², 1, 是)
快速排序 (nlogn, logn, 否)
插入类排序直接插入排序 (n², 1, 是)
折半插入(二分排序) ( n²,1,是)
希尔排序 (nlogn, 1, 否)
选择类排序简单选择排序 (n², 1, 否)
堆排序 (nlogn, 1, 否)
归并排序归并排序 (nlogn, n, 是)
基类排序基类排序 (dn, n, 是)

+++++++++

交换类排序源码

/**
 * <冒泡排序>
 * 根据轻气泡不能在重气泡之下的原则,从下往上扫描数组R,
 * 凡扫描到违反本原则的轻气泡,就使其向上“漂浮”
 */
public static void Bubble(int[] a) {
    // System.out.println("******冒泡排序******");
    for (int i = 0; i < a.length - 1; i++) {
        boolean exchange = false;
        for (int j = a.length - 1; j > i; j--) {
            if (a[j - 1] > a[j]) {
                swap(a, j - 1, j);
                exchange = true;
            }
        }
        if (!exchange) {
            return;
        }
    }
}
---------------------------------
/**
 * <快速排序>
 * 选取一个基准值,然后使 左边队列的值≦基准值≦右边队列的值
 * 通过递归调用对左右子区间快速排序得到结果
 */
public static void QSort(int[] a, int low, int high) {
    int i, j, temp;
    if (low < high) {
        i = low;
        j = high;
        temp = a[i];
        while (i < j) {
            while (i < j && a[j] > temp)
                j--;
            if (i < j) {
                a[i] = a[j];
                i++;
            }
            while (i < j && a[i] < temp)
                i++;
            if (i < j) {
                a[j] = a[i];
                j--;
            }
        }
        a[i] = temp;
        QSort(a, low, i - 1);
        QSort(a, i + 1, high);
    }
}

++++++
插入类排序源码

/**
 * <直接插入排序>
 * 从第一个元素开始,该元素可以认为已经被排好序。
 * 取出下一个元素,在已经排序的元素序列中从后往前扫描
 * 如果已排序的元素大于新元素,则将该元素与后一位的新元素交换位置
 */
public static void InsertSort(int[] a) {
    int i, j;
    // System.out.println("******插入排序******");
    for (i = 1; i < a.length; i++) {
        for (j = i; j > 0 && a[j] < a[j - 1]; j--) {
            swap(a, j, j - 1);
        }
    }
}
------------------------
/**
 * <折半插入排序(二分排序)>
 * 在直接插入排序的基础上,取出下一个元素时,不是扫描插入,
 * 而是通过二分查找的方式确定新元素要插入已排序中的位置,
 * 再直接后移位置,插入新元素。
 */
public static void BinaryInsertSort(int[] a) {
    int i, j, low, high, m, temp;
    // System.out.println("******二分排序******");
    for (i = 1; i <= a.length; i++) {
        temp = a[i];
        low = 1;
        high = i - 1;
        while (low <= high) {
            m = (low + high) / 2;
            if (temp < a[m])
                high = m - 1;
            else
                low = m + 1;
        } // while
        for (j = i - 1; j > high; j--)
            a[j + 1] = a[j];
        a[high + 1] = temp;
    }
}// BinaryInsertSort
-------------------------
/**
 * 希尔排序
 */
public static int ShellSort(int[] a, int dlta[], int t) {
    int count = 0;
    for (int i = 0; i < t; i++) {
        count = ShellInsert(a, dlta[i]);
    }
    return count;
}

public static int ShellInsert(int[] a, int dk) {
    int i, j, count = 0;
    for (i = dk + 1; i < a.length; i++) {
        if (a[i] < a[i - dk])
            a[0] = a[i];
        for (j = i - dk; j > 0 && a[0] < a[j]; j -= dk) {
            a[j + dk] = a[j];
            count++;
        }
        a[j + dk] = a[0];
    }
    return count;
}

++++++
选择类排序源码

/**
 * <选择排序>
 * 首先在未排序序列中找到最小元素,存放到排序序列的起始位置,
 * 然后,再从剩余未排序元素中继续寻找最小元素,放到排序序列末尾。
 * 以此类推,直到所有的元素均排序完毕。
 */
public static void SelectSort(int[] a) {
    // System.out.println("******选择排序******");
    for (int i = 0; i < a.length; i++) {
        boolean exchange = false;
        for (int j = i + 1; j < a.length; j++) {
            if (a[i] > a[j]) {
                swap(a, i, j);
                exchange = true;
            }
        }
        if (!exchange) {
            return;
        }
    }
}

4.判断两个数组中是否存在相同的数字 问题

有一个 O(n)算法。因为两个数组都是排好序的。所以只要一次遍历就行了。首先设两个下标,分别初始化为两个数组的起始地址,依次向前推进。推进的规则是比较两个数组中的数字,小的那个数组的下标向前推进一步,直到任何一个数组的下标到达数组末尾时,如果这时还没碰到相同的数字,说明数组中没有相同的数字。

public class Solution {
    // 判断两个已排好序的数组是否有相同的元素
    public Boolean find(int[] a, int size1, int[] b, int size2){
        int i=0,j=0;
        while(i<size1&&j<size2){
            if(a[i]==b[j])
                return true;
            if(a[i]>b[j])
                j++;
            if(a[i]<b[j])
                i++;
        }
        return false;
    }   
}

5.最大子序列 问题

给定一整数序列A1, A2,… An (可能有负数),求A1~An的一个子序列Ai~Aj,使得Ai到Aj的和最大
这里运用动态规划的思想求解,可以使时间复杂度降为O(n)

public class Solution {
    // 利用动态规划 查找最大子序列和
    static int max_sub2(int[] a, int size) {
        int i, temp_sum = 0, max = 0;
        for (i = 0; i < size; i++) {
            temp_sum += a[i];
            if (temp_sum > max)
                max = temp_sum;
        }
        return max;
    }
}

6.按单词反转字符串/按字母反转单词

三种变换形态都将囊括

public class Solution {
    // java实现字母反转 "Hello This is my house"-->"olleH sihT si ym esuoh"
    public static String word_reverse(String str){
        String reverse_str = "";
        String[] array = null;
        array = str.split(" ");
        for (int i = 0; i < array.length; i++) {
            StringBuffer sb = new StringBuffer(array[i]);
            reverse_str +=sb.reverse().toString()+" ";
        }
        return reverse_str;
    }

    // java实现单词反转 "Hello This is my house"-->"house my is This Hello"
    public static String word_reverse2(String str){
        String reverse_str = "";
        String[] array = null;
        array = str.split(" ");
        for (int i = array.length-1; i >= 0; i--) {
            reverse_str +=array[i].toString()+" ";
        }
        return reverse_str;
    }

    //java实现单词+字母反转 "Hello This is my house"-->"esuoh ym si sihT olleH"
    public static String word_reverse3(String str){
        String reverse_str = "";
        String[] array = null;
        array = str.split(" ");
        for (int i = array.length-1; i >= 0; i--) {
            StringBuffer sb = new StringBuffer(array[i]);
            reverse_str +=sb.reverse().toString()+" ";
        }
        return reverse_str;
    }
}

7.删除数组中重复的数字

问题:一个动态长度可变的数字序列,以数字0为结束标志,要求将重复的数字用一个数字代替

public class Solution {
    // Java中利用ArrayList去除重复的元素
    public static List removeDuplicates(int[] a) {
        List<Integer> list = new ArrayList<Integer>();
        for (int i = 0; i < a.length; i++) {
            if (!list.contains(a[i])) {
                list.add(a[i]);
            }
        }
        return list;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值