目录
有序列表二分查找
public boolean binarySearch(List<Integer> numbers, int value) {
if (numbers.size() == 0 || numbers.isEmpty()) {
return false;
}
int m = numbers.size() / 2;
int mValue = numbers.get(m);
if (value == mValue) {
return true;
}
if (value > mValue) {
List<Integer> rightNumbers = numbers.subList(m + 1, numbers.size());
return binarySearch(rightNumbers,value);
}
if (value < mValue) {
List<Integer> leftNumbers = numbers.subList(0, m);
return binarySearch(leftNumbers,value);
}
return false;
}
合并两个有序的数组,合并后依然有序
public int[] merge(int[] a,int[] b) {
int ai = 0;int bi = 0;int j = 0;
int[] result = new int[a.length + b.length];
while (ai<a.length && bi<b.length) {
if (a[ai] < b[bi]) {
result[j++] = a[ai];
ai ++;
}else {
result[j++] = b[bi];
bi++;
}
}
while (ai < a.length) {
result[j++] = a[ai++];
}
while (bi < b.length) {
result[j++] = b[bi++];
}
return result;
}
简单选择排序
- 先假设numbers[0]是最小值,第一趟,从第二个到最后一个元素找出比最小值更小的元素numbers[i],然后交换,则numbers[0]是最小值
- 然后找出次小值与numbers[1]交换
public void selectSort(int[] numbers){
for (int j = 0;j<numbers.length;j++) {
int min = numbers[j];
int minLocation = j;
for (int i = j+1; i < numbers.length; i++) {
if (numbers[i] < min) {
min = numbers[i];
minLocation = i;
}
}
// 将之前的最小值与现在的最小值交换位置
int temp = numbers[j];
numbers[j] = min;
numbers[minLocation] = temp;
}
}
快速排序
public int[] quikSort(int[] numbers,int low,int high) {
if (low<high) {
int middle = partition(numbers,low,high);
quikSort(numbers,low,middle-1);
quikSort(numbers,middle+1,high);
}
return numbers;
}
int partition(int[] numbers,int low, int high){
int middle = numbers[low];
while (low < high) {
// 从high端,寻找一个小于middle的记录
while (low < high && numbers[high] > middle) {
--high;
}
numbers[low] = numbers[high];
// 从low端,寻找一个大于middle的记录
while (low < high && numbers[low] < middle) {
++low;
}
numbers[high] = numbers[low];
}
numbers[low] = middle;
return low;
}
直接插入排序与希尔排序区别
希尔排序:按步长分组,在组内进行直接插入排序,慢慢缩小步长直至步长为1进行最后一次直接插入排序
冒泡排序
public static int[] bubbleSort(int[] numbers) {
boolean switched = false;
int tail = 1;
do {
for (int i = 0; i < numbers.length - tail; i++) {
if (numbers[i] > numbers[i+1]) {
int temp = numbers[i];
numbers[i] = numbers[i+1];
numbers[i+1] = temp;
switched = true;
}else {
// 若没有任何交换则说明已经排好序,跳出循环
switched = false;
}
}
// 每一轮循环都会确定最后一个元素的位置,每一轮可以少遍历一个元素
tail ++;
}while (switched == true);
return numbers;
}
给定一组单词,找出这组单词中属于某个给定单词的变位词(变位词指一个单词经过改编字母顺序后得到的另一个单词)
- 每个单词和其变位词都可有一个相同的算法签名,即按照字母顺序排序得到的字母序列
public class Variant {
Map<String, List<String>> signMap = new HashMap<>();
public Variant(final List<String> words) {
for (String word : words) {
String sign = getWordSign(word);
if (signMap.containsKey(sign)) {
signMap.get(sign).add(word);
}else {
List<String> wordList = new ArrayList<>();
wordList.add(word);
signMap.put(sign,wordList);
}
}
}
public List<String> getWords(String s){
String wordSign = getWordSign(s);
List<String> result = signMap.get(wordSign);
return result;
}
// 获得单词的签名
private String getWordSign(String word) {
byte[] bytes = word.getBytes();
Arrays.sort(bytes);
return new String(bytes);
}
}
递归
递归求和1+2+3+…+n
sum(n){
if(n>1){
return n+sum(n-1);
}else{
return 1;
}
}
递归阶乘n! = n * (n-1) * (n-2) * …* 1(n>0)
f(n){
if(n>1){
return n*f(n-1);
}else{
return 1
}
}
河内塔问题:一号杆上的珠子上小下大,借助2号杆把1号杆上的珠子移到三号杆而不改变珠子的上下顺序。(1)每次只能移动一个珠子(2)大珠子不能放在小珠子下面。最少移动多少次
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);
}
}
思想:
先将前n-1个移动到B,
再将最后一个移动到C,
最后将前n-1个移动到C