算法設計 第三次作業
阿新 • • 發佈:2018-04-22
count param RR ima static 整數 for else if bubuko
1 題目1 所有同學往右側看到的同學之和
青海大學的體育課經常排在上午3、4節,一節課下來大家都筋疲力盡、饑腸轆轆。將近下課,體育老師一吹口哨大家立即集合,不過這次集合大家都站成了一排,然後老師說向右看齊,這時每個人只能看到右側比自己矮的人頭,如果突然出現一個高於或等於自己身高的同學,那麽這名同學以及其右側的同學將會被擋住。那麽,問題來了,現給定所有同學的身高(假設體育課大家修煉了一種神秘技能,改變了自己的身高,(身高最大值為2*106),要求每個人能往右側看到的人數之和(建議使用long long存儲)。
輸入
輸入包括兩行
第一行是人數N(2<=N <= 2*106)
第二行包括N個數字 表示N個同學的身高
輸出
輸出一個整數,表示所有同學往右側看到的同學之和
1.1 思路
單調棧的思想運用,從左往右掃描
if 棧為空,或者棧頂元素大於當前元素
當前元素進棧。
else if 當前元素大於棧頂元素,
n = 棧頂元素對應的同學能看到的同學數,就是當前同學的編號減去棧頂同學編號再減去1,
sum += n (將這個值累加到sum)
在同學向右看的隊列的最後一個同學後面再插入一個同學,假設此同學是所有同學中最高的。保證每個同學都能從棧裏面出來。
1.2 java代碼(在最大矩形面積的代碼基礎上改)
import java.util.Stack; import java.math.BigInteger; public class Main { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub float[] array = {1.54f, 1.32f, 1.87f, 1.54f, 1.32f, 1.76f, 1.32f, 1.62f, 1.94f, 1.89f, 1.36f, 1.35f, 1.87f, 1.57f, 1.12f, 1.87f, 1.32f, 1.82f, 1.74f, 1.80f, 1.39f, 1.29f, 1.45f, 1.82f, 1.29f, 9999f}; // 9999f即為哨兵學生, 假設他的身高比所有人都高 System.out.print("學生的身高:"); for(float e: array) System.out.print(e + " "); BigInteger sum = sum_count(array); System.out.println("\n所有人右看齊人數之和:" + sum); } public static BigInteger sum_count(float[] array){ BigInteger sum = new BigInteger("0"); int len = array.length; Stack<Integer> s = new Stack<Integer>(); for(int i=0; i<len; i++){ if(!s.isEmpty() && array[i] < s.peek()) s.push(i); else { while(!s.isEmpty() && array[i] >= s.peek()){ int top = s.pop(); sum = sum.add(new BigInteger((i-top-1)+"")); } s.push(i); } } return sum; } }
1.3 結果
題目2 求任意給定數組的逆序對總數
數據量10^6 (利用歸並排序的思想)
2.1 思路
- 歸並排序思想
- 在歸並排序中,歸並操作時,在每次右半部的數小於左半部某個數i時,逆序對count進行累加一次,並將值返回
2.2 Java代碼
public class Main { public static void main(String[] args) { int[] array= {2, 3, 32, 5, 83, 9, 23, 4, 53, 4, 3, 2, 1, 2, 4, 7, 86, 21}; System.out.print("Array:"); for(int e: array) System.out.print(e + " "); System.out.println("\nInversion counts:" + inversion_count(array)); System.out.println("Sorted array:" + java.util.Arrays.toString(array)); } public static int inversion_count(int [] array) { if(array.length<=0) return 0; return merge_sort(array,0,array.length-1); } public static int merge_sort(int[] array,int lo,int hi){ if(lo>=hi) return 0; int mid=(lo+hi) >> 1; int lnums=merge_sort(array,lo,mid); int rnums=merge_sort(array,mid+1,hi); return lnums+rnums+merge(array,lo,mid,hi); } public static int merge(int[] array, int lo, int mid ,int hi){ int[] temp = new int[hi-lo+1]; int count = 0; int i = lo, j = mid+1, t = 0; while( i<=mid || j<=hi ){ if( i>mid && j<=hi ){ temp[t++] = array[j++]; continue; }else if(i<=mid && j>hi){ temp[t++] = array[i++]; continue; } if(array[i] > array[j]){ temp[t++] = array[j++]; count += mid-i+1; }else { temp[t++] = array[i++]; } } for(i=lo; i<=hi; i++) array[i] = temp[i-lo]; return count; } }
2.3 結果
算法設計 第三次作業