1. 程式人生 > >[日常刷題]leetcode D39

[日常刷題]leetcode D39

492. Construct the Rectangle

For a web developer, it is very important to know how to design a web page’s size. So, given a specific rectangular web page’s area, your job by now is to design a rectangular web page, whose length L and width W satisfy the following requirements:


1. The area of the rectangular web page you designed must equal to the given target area.

2. The width W should not be larger than the length L, which means L >= W.

3. The difference between length L and width W should be as small as possible.

You need to output the length L and the width W of the web page you designed in sequence.

Example:

Input: 4
Output: [2, 2]
Explanation: The target area is 4, and all the possible ways to construct it are [1,4], [2,2], [4,1]. 
But according to requirement 2, [1,4] is illegal; according to requirement 3,  [4,1] is not optimal compared to [2,2]. So the length L is 2, and the width W is 2.

Note:

  1. The given area won’t exceed 10,000,000 and is a positive integer
  2. The web page’s width and length you designed must be positive integers.

Solution in C++:

關鍵點:

  • 折半

思路:

  • 因為看到例子裡面有完全平方數的例子,讓我覺得可以從這裡下手,首先是如果是完全平方數的話那就返回兩個相等的即可,這裡我之前犯了個錯誤,我認為 area % i == 0即可代表完全平方數,在測試6的時候出現了錯誤,所以這裡換回了 iii * i == area的判斷條件。然後就是下面的邏輯,還是拿6和5來舉例,正確答案分別應該是3 * 2和5*1這裡一個可以看出來l
    的最大值應該要麼是可以完全平方求根號之後的結果要麼是比它大的,然後再就是w一定是大於1的,所以就出現了下面的迴圈操作。
vector<int> constructRectangle(int area) {
        vector<int> result;
        int l, m;
        l = sqrt(area);
        
        if ( l* l == area){   // 是完全平方數
            result.push_back(l);
            result.push_back(l);
        } else{
            l = ceil(area*1.0/l);
            while(l >= 1){
                if (area % l == 0)
                {
                    int tmp = max(l, area/l);
                    m = area / tmp;
                    l = tmp;
                    break;
                }
                --l;
            }
            result.push_back(l);
            result.push_back(m);
        }
        
        return result;
    }

496. Next Greater Element I

You are given two arrays (without duplicates) nums1 and nums2where nums1’s elements are subset of nums2. Find all the next greater numbers for nums1's elements in the corresponding places of nums2.

The Next Greater Number of a number x in nums1 is the first greater number to its right in nums2. If it does not exist, output -1 for this number.

Example 1:

Input: nums1 = [4,1,2], nums2 = [1,3,4,2].
Output: [-1,3,-1]
Explanation:
    For number 4 in the first array, you cannot find the next greater number for it in the second array, so output -1.
    For number 1 in the first array, the next greater number for it in the second array is 3.
    For number 2 in the first array, there is no next greater number for it in the second array, so output -1.

Example 2:

Input: nums1 = [2,4], nums2 = [1,2,3,4].
Output: [3,-1]
Explanation:
    For number 2 in the first array, the next greater number for it in the second array is 3.
    For number 4 in the first array, there is no next greater number for it in the second array, so output -1.

Note:

  1. All elements in nums1 and nums2 are unique.
  2. The length of both nums1 and nums2 would not exceed 1000.

Solution in C++:

易錯點:

  • 本位置第一個大的數不一定是右邊最大的數

思路:

  • 最開始我的想法很naive,使用map記錄nums裡面每個位置對應的第一個大的數的值就可以了,然後為了簡化,我還認為從後到前的方式只用比較後一個和其對應的value即可,但是後來發現這裡的邏輯bug就是我上面提到的易錯點,然後我修改了這個比較邏輯,改成了從當前位置一直掃描到比自己大的數,(其實這裡可以優化到掃描到value為-1的數,然後比較和那個數的大小情況即可)。
vector<int> nextGreaterElement(vector<int>& findNums, vector<int>& nums) {
        map<int, int> maps;
        vector<int> result;
        for(int i = nums.size() - 1; i >= 0; --i){
            if (i == nums.size() - 1){
                maps[nums[i]] = -1;
            } else{
                if (nums[i+1] > nums[i])
                    maps[nums[i]] = nums[i+1];
                else if (maps[nums[i+1]] > nums[i])
                    maps[nums[i]] = maps[nums[i+1]];
                else if (maps[nums[i+1]] != -1){
                    int j = i + 1;
                    while(j < nums.size()){
                        if (nums[j] > nums[i]){
                            maps[nums[i]] = nums[j];
                            break;
                        }
                        ++j;
                    }
                    
                    if (j == nums.size())
                        maps[nums[i]] = -1;
                }
                else
                    maps[nums[i]] = -1;
            }
        }
        
        for(auto num : findNums){
            result.push_back(maps[num]);
        }
        
        return result;
    }

500. Keyboard Row

Given a List of words, return the words that can be typed using letters of alphabet on only one row’s of American keyboard like the image below.
在這裡插入圖片描述

Example:

Input: ["Hello", "Alaska", "Dad", "Peace"]
Output: ["Alaska", "Dad"]

Solution in C++:

關鍵點:

  • 字母對應關係

思路:

  • 這裡也是一個很簡單的想法,就是在鍵盤中一行的字母對應同一個value值,然後構造一下查詢的陣列表即可。
vector<string> findWords(vector<string>& words) {
        vector<string> result;
        vector<int> maps(26, 0);
        // 初始化表
        maps['Q' - 'A'] = 1;
        maps['W' - 'A'] = 1;
        maps['E' - 'A'] = 1;
        maps['R' - 'A'] = 1;
        maps['T' - 'A'] = 1;
        maps['Y' - 'A'] = 1;
        maps['U' - 'A'] = 1;
        maps['I' - 'A'] = 1;
        maps['O' - 'A'] = 1;
        maps['P' - 'A'] = 1;
        
        maps['A' - 'A'] = 2;
        maps['S' - 'A'] = 2;
        maps['D' - 'A'] = 2;
        maps['F' - 'A'] = 2;
        maps['G' - 'A'] = 2;
        maps['H' - 'A'] = 2;
        maps['J' - 'A'] = 2;
        maps['K' - 'A'] = 2;
        maps['L' - 'A'] = 2;
        
        maps['Z' - 'A'] = 3;
        maps['X' - 'A'] = 3;
        maps['C' - 'A'] = 3;
        maps['V' - 'A'] = 3;
        maps['B' - 'A'] = 3;
        maps['N' - 'A'] = 3;
        maps['M' - 'A'] = 3;
        
        for(auto word : words){
            int i = 0;
            int tmp = maps[toupper(word[i]) - 'A'];
            bool flag = true;
            for(; i < word.size(); ++i){
                if (maps[toupper(word[i]) - 'A'] != tmp){
                    flag = false;
                    break;
                }
            }
            
            if(flag)
                result.push_back(word);
        }
        return result;
    }

小結

今天leetcode介面換新了,我很不習慣啊,熟悉花了一點時間,在彆扭中實在習慣不了,就切回來了。哈哈。不過今天也是練練手。找找自己的邏輯bug。之前有提到感覺沒什麼進步,今天走在路上突然想通了,我缺少一些邏輯上的鍛鍊,刷題也是一個不錯的鍛鍊。(自己可以想到一些解決的途徑但是無法code出來,大問題!!!)