冒泡排序、雙向冒泡排序、插入排序、選擇排序、快速排序
/**
* 冒泡排序
通過相鄰元素的比較和交換,使得每一趟循環都能找到未有序數組的最大值或最小值。
最好:O(n),只需要冒泡一次數組就有序了。
最壞:O(n²)
平均:
*/
/**
* 單向冒泡排序
* 通過相鄰元素的比較和交換,使得每一趟循環都能找到未有序數組的最大值或最小值。
*/
public class Sort {
public static int[] bubbleSort(int[] nums){
// 如果一輪比較中沒有需要交換的數據,則說明數組已經有序。
boolean flag = true;
for (int i = 0; i < nums.length; i++) {
for (int j = 0; j < nums.length-1; j++) {
if (nums[j]>nums[j+1]){
int tmp = nums[j];
nums[j] = nums[j+1];
nums[j+1] =tmp;
flag = false;
}
}
if (flag){
return nums;
}
}
return nums;
}
/**
* 雙向冒泡排序
*普通的冒泡排序在一趟循環中只能找出一個最大值或最小值,雙向冒泡則是多一輪循環既找出最大值也找出最小值。
*/
public static int[] bubbleSortTwoWays(int[] nums){
int low = 0;
int high = nums.length-1;
while (low<high){
boolean flag = true;
for (int i = low; i < high; i++) {
if (nums[i]> nums[i+1]){
int tmp = nums[i];
nums[i] =nums[i+1];
nums[i+1] = tmp;
flag = false;
}
}
high--;
for (int i = high; i >low ; i--) {
if (nums[i]< nums[i-1]){
int tmp = nums[i];
nums[i] =nums[i-1];
nums[i-1] = tmp;
flag = false;
}
}
low ++;
if (flag){
return nums;
}
}
return nums;
}
/**
* 選擇排序
和冒泡排序相似,區別在於選擇排序是將每一個元素和它後面的元素進行比較和交換。
最好:O(n²)
最壞:O(n²)
平均:
*/
public static void selectSort(int[] nums){
for (int i = 0; i < nums.length; i++) {
for (int j = i+1; j < nums.length; j++) {
if (nums[i]>nums[j]){
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
}
}
}
/**
* 插入排序
以第一個元素作爲有序數組,其後的元素通過在這個已有序的數組中找到合適的位置並插入。
最好:O(n),原數組已經是升序的。
最壞:O(n²)
平均:
*/
public static void insertSort(int[] nums){
for (int i = 1; i < nums.length; i++) {
int tmp = nums[i];
int j = i;
while (j>=0 && tmp < nums[j-1]){
nums[j] = nums[j-1];
j--;
}
nums[j] = tmp;
}
}
/**
* 快速排序
* @param nums
*/
public static void quickSortMain(int[] nums){
quickSort(nums,0,nums.length-1);
}
public static void quickSort(int[] nums,int left,int right){
if (left>right){
return;
}
int i,j,t,tmp;
tmp = nums[left];////tmp中存的就是基準數
i=left;
j= right;
while (i != j){
//順序很重要,要先從右邊開始找
while (nums[j]>= tmp && i<j){
j--;
}
//再找右邊的
while (nums[i]<= tmp && i<j){
i++;
}
//交換兩個數在數組中的位置
t =nums[i];
nums[i]=nums[j];
nums[j]=t;
}
//最終將基準數歸位
nums[left] = nums[i];
nums[i]=tmp;
quickSort(nums,left,i-1);
quickSort(nums,i+1,right);
}
public static void main(String[] args) {
int[] a = new int[]{1,3,5,7,2,4,6,9,10,8};
// bubbleSort(a);
// bubbleSortTwoWays(a);
// selectSort(a);
// insertSort(a);
quickSortMain(a);
for (int i = 0; i < a.length; i++) {
System.out.print(a[i]);
}
}
漢諾塔
漢諾塔(又稱河內塔)問題是源於印度一個古老傳說的益智玩具。大梵天創造世界的時候做了三根金剛石柱子,在一根柱子上從下往上按照大小順序摞着64片黃金圓盤。大梵天命令婆羅門把圓盤從下面開始按大小順序重新擺放在另一根柱子上。並且規定,在小圓盤上不能放大圓盤,在三根柱子之間一次只能移動一個圓盤。
後來,這個傳說就演變爲漢諾塔遊戲,玩法如下:
- 1.有三根杆子A,B,C。A杆上有若干碟子
- 2.每次移動一塊碟子,小的只能疊在大的上面
- 3.把所有碟子從A杆全部移到C杆上
以下實例演示了漢諾塔算法的實現:
public static void main(String[] args) {
int nDisks = 3;
doTowers(nDisks, 'A', 'B', 'C');
}
public static void doTowers(int topN, char from, char inter, char to) {
if (topN == 1){
System.out.println("Disk 1 from "
+ from + " to " + to);
}else {
doTowers(topN - 1, from, to, inter);
System.out.println("Disk "
+ topN + " from " + from + " to " + to);
doTowers(topN - 1, inter, from, to);
}
}
二分查找
/**
* 二分查找
* @param nums
* @param target
* @return
*/
public static int search(int[] nums, int target) {
int l = 0,r=nums.length-1;
while (l<=r){
int mid = l+(r-1)/2;
// int mid = (l + r)/2;
if (nums[mid] == target){
return mid;
}
if (nums[mid]> target){
r=mid-1;
}
if (nums[mid]< target){
l=mid+1;
}
}
return -1;
}
合併兩個有序數組
public static int[] merge(int[] a,int[] b){
int[] c= new int[a.length+b.length];
int i=0,j=0;
int t = 0;
while (t<c.length){
if (i>=a.length && j< b.length){
c[t++]=b[j++];
}
if (j>=b.length && i< a.length){
c[t++]=a[i++];
}
if (i<a.length && j<b.length){
int d = a[i]<b[j]?a[i++]:b[j++];
System.out.println("==" +d);
c[t++]=d;
}
}
return c;
}
public static int[] merge2(int[] a,int[] b){
int[] c= new int[a.length+b.length];
int i=0,j=0;
int t = 0;
while (i<a.length && j<b.length){
c[t++] = a[i]<b[j]?a[i++]:b[j++];
}
if (i<a.length){
while (i<a.length){
c[t++] =a[i++];
}
}
if (j<b.length){
while (i<b.length){
c[t++] =b[j++];
}
}
return c;
}
public static int[] merge3(int[] a,int[] b){
int[] c= new int[a.length+b.length];
int t=0;
for (int i = 0; i < a.length; i++) {
c[t] = a[i];
t++;
}
for (int i = 0; i < b.length; i++) {
c[t] = b[i];
t++;
}
for (int i = 0; i < c.length; i++) {
for (int j = 0; j <c.length ; j++) {
if (c[i]>c[j]){
int tmp = c[i];
c[i] = c[j];
c[j] = tmp;
}
}
}
return c;
}
public void merge5(int[] nums1, int[] nums2) {
int m = nums1.length;
int n = nums2.length;
// Make a copy of nums1.
int [] nums1_copy = new int[m];
System.arraycopy(nums1, 0, nums1_copy, 0, m);
// Two get pointers for nums1_copy and nums2.
int p1 = 0;
int p2 = 0;
// Set pointer for nums1
int p = 0;
// Compare elements from nums1_copy and nums2
// and add the smallest one into nums1.
while ((p1 < m) && (p2 < n))
nums1[p++] = (nums1_copy[p1] < nums2[p2]) ? nums1_copy[p1++] : nums2[p2++];
// if there are still elements to add
if (p1 < m)
System.arraycopy(nums1_copy, p1, nums1, p1 + p2, m + n - p1 - p2);
if (p2 < n)
System.arraycopy(nums2, p2, nums1, p1 + p2, m + n - p1 - p2);
}
public static void main(String[] args) {
int[] a = new int[]{1,3,5,7,9,10};
int[] b = new int[]{2,4,6,8};
int[] c = merge2(a,b);
for (int i = 0; i < c.length; i++) {
System.out.println(c[i]);
}
}
最長迴文數
/**
* 最長迴文數 中心擴展法
* @param s
* @return
*/
public static String longestPalindrome(String s) {
if (s == null || s.length() < 1) {
return "";
}
int start = 0, end = 0;
for (int i = 0; i <s.length() ; i++) {
int len = expandAroundCenter(s,i,i);
int len1 = expandAroundCenter(s,i,i+1);
len = Math.max(len,len1);
if (len> end -start){
start = i-(len -1)/2;
end = i+ len/2;
}
}
return s.substring(start,end+1);
}
public static int expandAroundCenter(String s,int l,int r){
while (l >= 0 && r<s.length() && s.charAt(l) == s.charAt(r)){
l--;
r++;
}
return r-l -1;
}
/**
* 中心擴展算法
* @param s
* @return
*/
public static String longestPalindrome3(String s){
if(s == null || s.length()<1){
return "";
}
StringBuffer sb = new StringBuffer();
for (int i = 0; i <s.length() ; i++) {
sb.append("#");
sb.append(s.charAt(i));
}
sb.append("#");
int maxLen = 0;
String t = sb.toString();
int start = 0, end = 0;
for (int i = 0; i < t.length(); i++) {
maxLen = Math.max(subpalidromelen(sb.toString(),i),maxLen);
if (maxLen> end -start){
start = i-(maxLen -1);
end = i+ (maxLen-1);
}
}
String tt = t.substring(start,end+1);
return tt.replace("#","");
}
public static int subpalidromelen(String s,int i){
int len = 0;
for (int k=0;k<=i&& k<(s.length()-i);k++){
if (s.charAt(i-k) == s.charAt(i+k)){
len ++;
} else {
break;
}
}
return len;
}
/**
* 窮舉法,窮舉所有子串,找出是迴文串的子串,統計出最長的那一個。
* @param s
* @return
*/
public static String longestPalindrome2(String s){
if (s == null || s.length()<1){
return "";
}
int len = 0;
int start =0,end = 0;
for (int i = 0; i < s.length(); i++) {
for (int j = i+1; j <= s.length(); j++) {
if (isPalindrome(s.substring(i,j))){
len= Math.max(len,j-i);
if (len > end -start){
start = i;
end = j;
}
};
}
}
return s.substring(start,end);
}
public static boolean isPalindrome(String s){
int mid = s.length()/2;
int last = s.length()-1;
for (int i = 0; i < mid; i++) {
if (s.charAt(i) != s.charAt(last -i)){
return false;
}
}
return true;
}
public static void main(String[] args) {
// String a = "babac";
String a = "abba";
System.out.println(longestPalindrome(a));
}
翻轉鏈表
public ListNode reversetList(ListNode head){
ListNode prev = null;
ListNode curr = head;
while (curr != null){
ListNode nextTemp = curr.next;
curr.next=prev;
prev = curr;
curr = nextTemp;
}
return prev;
}
//遞歸
public ListNode reverseList(ListNode head) {
if (head == null || head.next == null) return head;
ListNode p = reverseList(head.next);
head.next.next = head;
head.next = null;
return p;
}