LeetCode 的 Runtime 指標是否可信?

【原文鏈接】http://www.changxuan.top/2019/02/13/leetcode-的-runtime-指標是否可信?/

今天做完  Roman to Integer 這道題後感覺運行時間稍長就開始了優化代碼。然後就發現越優化越不科學!拿來中文版的 leetCode 網站來運行發現更加神奇。

題目詳情

Roman numerals are represented by seven different symbols: IVXLCD and M.

Symbol       Value
I             1
V             5
X             10
L             50
C             100
D             500
M             1000

For example, two is written as II in Roman numeral, just two one's added together. Twelve is written as, XII, which is simply X + II. The number twenty seven is written as XXVII, which is XX + V + II.

Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is not IIII. Instead, the number four is written as IV. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written as IX. There are six instances where subtraction is used:

  • I can be placed before V (5) and X (10) to make 4 and 9. 
  • X can be placed before L (50) and C (100) to make 40 and 90. 
  • C can be placed before D (500) and M (1000) to make 400 and 900.

Given a roman numeral, convert it to an integer. Input is guaranteed to be within the range from 1 to 3999.

Example 1:

Input: "III"
Output: 3

Example 2:

Input: "IV"
Output: 4

Example 3:

Input: "IX"
Output: 9

Example 4:

Input: "LVIII"
Output: 58
Explanation: L = 50, V= 5, III = 3.

Example 5:

Input: "MCMXCIV"
Output: 1994
Explanation: M = 1000, CM = 900, XC = 90 and IV = 4.

但看到題目的時候,想到可以用到鍵值對。然後針對特殊的規則,如果沒到最後一個字母就判斷當前字母表示的數值是否小於後一個字母表示的數值... ...我的第一個版本代碼如下:


public static int getValues(String roman){
		int values = 0;
		Map <Character,Integer> map = new HashMap();
		map.put('I', 1);
		map.put('V', 5);
		map.put('X', 10);
		map.put('L', 50);
		map.put('C', 100);
		map.put('D', 500);
		map.put('M', 1000);
		
		char[] romanArray = roman.toCharArray();
		
		for(int i = 0; i < romanArray.length; i++){
			if((i != romanArray.length-1)&&(map.get(romanArray[i]) < map.get(romanArray[i+1]))){
				values = values + (map.get(romanArray[i+1]) - map.get(romanArray[i]));
				i++;
			}else{
				values += map.get(romanArray[i]);
			}
			
		}
		return values;		
	}

Submission Detail

3999 / 3999 test cases passed.Status: Accepted
Runtime: 43 msSubmitted: 1 hour, 42 minutes ago

You are here! 
Your runtime beats 65.95 % of java submissions.

然後想到可以用用一個函數來替代 HashMap 的作用。第二個版本的代碼:

class Solution {
    public static int val(char rom){
		int temp = 0;
		switch (rom){
		case 'I':
			temp = 1;
			break;
		case 'V':
			temp = 5;
			break;
		case 'X':
			temp = 10;
			break;
		case 'L':
			temp = 50;
			break;
		case 'C':
			temp = 100;
			break;
		case 'D':
			temp = 500;
			break;
		case 'M':
			temp = 1000;
		}
		return temp;
	}
    public int romanToInt(String s) {
       int values = 0;
		char[] romanArray = s.toCharArray();
		for(int i = 0; i < romanArray.length; i++){
			if((i != romanArray.length-1)&&(val(romanArray[i]) < val(romanArray[i+1]))){
				values = values + (val(romanArray[i+1]) - val(romanArray[i]));
				i++;
			}else{
				values += val(romanArray[i]);
			}
			
		}
		
		return values;
    }
}

Submission Detail

3999 / 3999 test cases passed.Status: Accepted
Runtime: 38 msSubmitted: 47 minutes ago

You are here! 
Your runtime beats 88.23 % of java submissions.

看來是有一點進步的!但是我實在想不到如何縮短運行時間了,所以我去看別人的

32 ms解法

然後我通過 ctrl v + ctrl c,運行:

39 ms ... ...

還沒我的代碼運行時間短!然後我打開中文版的 leetCode 將上面的的代碼依次複製運行,運行結果如下:

其中120 ms 是我從中文版網站中找的最優解代碼... ...

總結

  • 這是玄學
  • 英文版的服務器比中文版的服務器好
  • 儘量挑沒人做題的時候提交
  • 以後除非有更好的思路和方法,再也不做優化!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章