【Java基礎總結】-演算法題總結
阿新 • • 發佈:2019-01-31
常見資料結構和演算法程式設計題
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;
}
}