一、單鏈表倒序排列
public static void revse(Node node){
//拿到頭結點
Node head = node;
//拿到當前循環的節點
Node curNode = node.next;
//頭結點的next置爲null
head.next = null;
//如果當前節點不爲空
while(curNode != null){
//取出當前節點的下一個節點,作爲下次循環遍歷用
Node next = curNode.next;
//將當前節點的下一個節點,指向前一個節點
curNode.next = head;
//前一個節點指向當前節點
head = curNode;
//把取出的下一個節點作爲當前節點,繼續循環
curNode = next;
}
}
算法不難,網上案例比較多,但是就是在寫的時候思路亂了,沒寫好,只把思路說出來了
二、兩個數組交叉打印,線程同時start,必須從1開始打印
//題目要求必須打出1,2,3,4,5,6,7,8,9,10
private static int[] arr1 = new int[]{1,3,5,7,9};
private static int[] arr2 = new int[]{2,4,6,8,10};
//線程間通信用volatile修飾的關鍵字
private static volatile boolean status = false;
public static void main(String[] args) {
//使用jdk提供的鎖
ReentrantLock lock = new ReentrantLock();
Condition condition = lock.newCondition();
//開啓線程並在循環開始的時候加鎖
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
for(int i =0;i< arr2.length;i++){
lock.lock();
try {
//如果status!=true,那麼當前線程阻塞(await會釋放鎖)
if(status != true){
condition.await();
}
//打印數據
System.out.println(arr2[i]);
//喚醒其他線程
condition.signalAll();
try {
//阻塞當前線程
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
} catch (Exception e) {
lock.unlock();
}
}
}
});
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < arr1.length; i++) {
lock.lock();
try {
//當前線程拿到鎖之後打印出1
System.out.println(arr1[i]);
//status置爲true
if(status ==false) {
status = true;
}
//喚醒正在阻塞的線程
condition.signalAll();
try {
//當前線程阻塞
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
} catch (Exception e) {
lock.unlock();
}
}
}
});
thread1.start();
thread2.start();
}
這道題考察的是對線程的等待喚醒機制,及線程間通信的理解
三,發紅包算法,如何公平的將100元,分配給10個人(二倍均值法)
/**
* 發紅包算法,入參人數和總金額,返回,人和金額的map
* @param person
* @param totalMoney
* @return
*/
public static Map<Integer,Double> sendRedPackage(Integer person,Double totalMoney){
if(person<=0 || totalMoney<=0.0){
return new HashMap<>();
}
Map<Integer,Double> result = new HashMap<>();
for(int i = 0;i<person;i++){
if(i == person -1){
result.put(i,new BigDecimal(totalMoney+"").setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue());
break;
}
double avgMoney = totalMoney / (person-i);
double money = new Random().nextDouble() * avgMoney * 2;
money = new BigDecimal(money+"").setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();
if(money<0.01){
money = 0.01;
}
if(money>avgMoney){
money =new BigDecimal(avgMoney+"").setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();
}
result.put(i,money);
totalMoney = totalMoney - money;
}
return result;
}
四,一個不知道長度的鏈表,輸出鏈表中倒數第n個值
//實現思路,使用兩個指針,步長爲n,當第一個指針走到最後的時候,此時第二個指針的位置就是倒數第n個值
public static Node sout(Node node,int n){
int i = 0;
Node result =null;
Node firstNode = node;
Node secondNode = node;
while (firstNode!=null){
i++;
if(i >= n){
result = secondNode;
secondNode = secondNode.next;
}
firstNode = firstNode.next;
if(firstNode ==null){
break;
}
}
return result;
}
五,快速排序算法及優化
public static int[] arr = new int[]{4,2,3,7,6,5,0,9,1};
public static void main(String[] args) {
quickSort(arr,0,arr.length-1);
System.out.println(arr);
}
public static void quickSort(int[] arr,int low ,int high){
if(low > high){
return;
}
int temp = arr[low];
int i = low;
int j = high;
int t ;
//將數組中按照基準值左右排開
while(i<j){
while(temp<=arr[j]&&i<j){
j--;
}
while(temp>=arr[i]&&i<j){
i++;
}
if(i<j){
t = arr[i];
arr[i]= arr[j];
arr[j] = t;
}
}
//交換基準值和第i或j的值
arr[low] = arr[i];
arr[i] = temp;
//交換完成後,左右兩邊分別遞歸按照二分法思想做排序
quickSort(arr,low,j-1);
quickSort(arr,j+1,high);
}
六,打印金額問題,給定的一個三位數,輸出對應的中文金額,如365,輸出爲叄佰陸拾伍元整,儘可能多的處理一些邊界值
考察的是對事物思考的全面性,邊界值的處理
//僅支持三位整數,四位及以上或者小數不支持
public static void printToString(Integer money){
String[] capital = { "零", "壹", "貳", "叄", "肆", "伍", "陸", "柒", "捌", "玖" };
String[] integerUnit = { "", "拾", "佰", "仟", "萬" };
int length = String.valueOf(money).length();
for(int i = length;i>0;i--){
int every = money / (int) (Math.pow(10, (i - 1)));
money = money % (int) (Math.pow(10, (i - 1)));
if(every==0 && money==0){
break;
}
System.out.print(capital[every]);//輸出數字大寫
if(every ==0){
continue;
}
System.out.print(integerUnit[i - 1]);//輸出單位,
}
System.out.print("元整");
}
以上是關於美團和滴滴最近相關的算法面試題,有些當時只給出了思路,但是沒有寫出來,事後總結還是因爲當時思路並
不是太明確,導致寫的時候思路不清晰只能給出大概的實現思路
總結出來就是,看到算法題,第一步應該明確要考查的點,第二步就應該把整體的實現思路在腦子裏過一遍,分析完後在
動筆去寫,算法題有很多,但是大多數的解決思路都差不太多,只要基礎夠好,臨場發揮問題不太大,就算是最後沒有實
現,但是也要給出具體的實現思路