LeetCode 11-20 题

11. 盛最多水的容器

难度中等1811

给你 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (iai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (iai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

说明:你不能倾斜容器,且 n 的值至少为 2。

 

LeetCode 11-20 题_第1张图片

图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。

 

示例:

输入:[1,8,6,2,5,4,8,3,7]
输出:49

双指针法,缩减搜索空间的思想去考虑题解,做出来之后还是有可能做不出来。

用一句话概括双指针解法的要点:指针每一次移动,都意味着排除掉了一个柱子

(看动图!)

作者:nettee
链接:https://leetcode-cn.com/problems/container-with-most-water/solution/on-shuang-zhi-zhen-jie-fa-li-jie-zheng-que-xing-tu/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

class Solution {
public:
    int maxArea(vector& height) {
        int x=0,y=height.size()-1;
        int ans=0;
        while(x!=y){
            int tmp=min(height[x],height[y])*(y-x);
            if(tmp>ans) ans=tmp;
            if(min(height[x],height[y])==height[x]){
                x++;
            }else y--;
        }
        return ans;

    }
};

 

12. 整数转罗马数字

难度中等404

罗马数字包含以下七种字符: I, V, X, LCD 和 M

字符          数值
I             1
V             5
X             10
L             50
C             100
D             500
M             1000

例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做  XXVII, 即为 XX + V + II 。

通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:

  • I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
  • X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。 
  • C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。

给定一个整数,将其转为罗马数字。输入确保在 1 到 3999 的范围内。

示例 1:

输入: 3
输出: "III"

示例 2:

输入: 4
输出: "IV"

示例 3:

输入: 9
输出: "IX"

示例 4:

输入: 58
输出: "LVIII"
解释: L = 50, V = 5, III = 3.

示例 5:

输入: 1994
输出: "MCMXCIV"
解释: M = 1000, CM = 900, XC = 90, IV = 4.

好像就是非常普通的贪心hhh

class Solution {
public:
    unordered_map mp={
    {1,"I"},{5,"V"},{10,"X"},{50,"L"},{100,"C"},{500,"D"},{1000,"M"},
    {4,"IV"},{9,"IX"},{40,"XL"},{90,"XC"},{400,"CD"},{900,"CM"}};
    vector d={1000,900,500,400,100,90,50,40,10,9,5,4,1};
    string intToRoman(int num) {
        if(num==0) return "";
        for(int i=0;i=d[i]){
                return mp[d[i]]+intToRoman(num-d[i]);break;
            }
        }
        return "";//
    }
};

 

13. 罗马数字转整数

难度简单1028

罗马数字包含以下七种字符: I, V, X, LCD 和 M

字符          数值
I             1
V             5
X             10
L             50
C             100
D             500
M             1000

例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做  XXVII, 即为 XX + V + II 。

通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:

  • I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
  • X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。 
  • C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。

给定一个罗马数字,将其转换成整数。输入确保在 1 到 3999 的范围内。

 

示例 1:

输入: "III"
输出: 3

示例 2:

输入: "IV"
输出: 4

示例 3:

输入: "IX"
输出: 9

示例 4:

输入: "LVIII"
输出: 58
解释: L = 50, V= 5, III = 3.

示例 5:

输入: "MCMXCIV"
输出: 1994
解释: M = 1000, CM = 900, XC = 90, IV = 4.

 

提示:

  • 题目所给测试用例皆符合罗马数字书写规则,不会出现跨位等情况。
  • IC 和 IM 这样的例子并不符合题目要求,49 应该写作 XLIX,999 应该写作 CMXCIX 。
  • 关于罗马数字的详尽书写规则,可以参考 罗马数字 - Mathematics 。

啊......反正方法好像都差不多,但是执行效率差很多...?

class Solution {
    public int romanToInt(String s) {
        int sum = 0;
        int preNum = getValue(s.charAt(0));
        for(int i = 1;i < s.length(); i ++) {
            int num = getValue(s.charAt(i));
            if(preNum < num) {
                sum -= preNum;
            } else {
                sum += preNum;
            }
            preNum = num;
        }
        sum += preNum;
        return sum;
    }
    
    private int getValue(char ch) {
        switch(ch) {
            case 'I': return 1;
            case 'V': return 5;
            case 'X': return 10;
            case 'L': return 50;
            case 'C': return 100;
            case 'D': return 500;
            case 'M': return 1000;
            default: return 0;
        }
    }
}

作者:donespeak
链接:https://leetcode-cn.com/problems/roman-to-integer/solution/yong-shi-9993nei-cun-9873jian-dan-jie-fa-by-donesp/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

14. 最长公共前缀

难度简单1254

编写一个函数来查找字符串数组中的最长公共前缀。

如果不存在公共前缀,返回空字符串 ""

示例 1:

输入: ["flower","flow","flight"]
输出: "fl"

示例 2:

输入: ["dog","racecar","car"]
输出: ""
解释: 输入不存在公共前缀。

说明:

所有输入只包含小写字母 a-z 。

这个效率还可以诶??

class Solution {
public:
    string longestCommonPrefix(vector& strs) {
        string ans="";
        int n=strs.size();
        if(n==0) return "";
        unordered_map mp;
        int index=0;
        while(1){
            for(int i=0;i

15. 三数之和

难度中等2564

给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。

注意:答案中不可以包含重复的三元组。

 

示例:

给定数组 nums = [-1, 0, 1, 2, -1, -4],

满足要求的三元组集合为:
[
  [-1, 0, 1],
  [-1, -1, 2]
]
class Solution {
public:
    vector> twoSum(vector nums,int target,int start){
        int l=start;int r=nums.size()-1;
        vector> ans;
        while(ltarget){
                r--;
                while(l> threeSum(vector& nums) {
        vector> ans;
        sort(nums.begin(),nums.end());
        for(int i=0;i> tuples=twoSum(nums,0-nums[i],i+1);
            for(vector& tuple:tuples){
                tuple.push_back(nums[i]);
                ans.push_back(tuple);
            }
            while(i

16. 最接近的三数之和

难度中等565

给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在唯一答案。

 

示例:

输入:nums = [-1,2,1,-4], target = 1
输出:2
解释:与 target 最接近的和是 2 (-1 + 2 + 1 = 2) 。
class Solution {
public:
    //最接近的两数之和??
    int twoSum(vector& nums,int target,int start){
        int l=start;int r=nums.size()-1;
        int ans;int difference=10e8;
        while(ltarget){
                r--;while(l& nums, int target) {
        //-4 -1  1 2
        //所有不重复的...
        int ans;
        int difference=10e8;
        sort(nums.begin(),nums.end());
        for(int i=0;i
class Solution {
    public int threeSumClosest(int[] nums, int target) {
        Arrays.sort(nums);
        int ans = nums[0] + nums[1] + nums[2];
        for(int i=0;i target)
                    end--;
                else if(sum < target)
                    start++;
                else
                    return ans;
            }
        }
        return ans;
    }
}

17. 电话号码的字母组合

难度中等909

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。

给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

LeetCode 11-20 题_第2张图片

示例:

输入:"23"
输出:["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].

说明:
尽管上面的答案是按字典序排列的,但是你可以任意选择答案输出的顺序。

平平无奇的dfs


class Solution {
public:
    vector letterCombinations(string digits) {
        if (digits.length() == 0) return res;
        backTrace(digits, 0);
        return res;
    }
private:
    unordered_map phoneString {
        {'2',"abc"},
        {'3',"def"},
        {'4',"ghi"},
        {'5',"jkl"},
        {'6',"mno"},
        {'7',"pqrs"},
        {'8',"tuv"},
        {'9',"wxyz"},
    };
    string s;
    vector res;
    void backTrace(string digits, int index)
    {
        if(digits.size() == index) {
            res.push_back(s);
        }
        for (int i = 0; i < phoneString[digits[index]].size(); ++i) {
            s += phoneString[digits[index]][i];
            backTrace(digits, index+1);
            s.pop_back();
        }
    }
};

18. 四数之和

难度中等564

给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?找出所有满足条件且不重复的四元组。

注意:

答案中不可以包含重复的四元组。

示例:

给定数组 nums = [1, 0, -1, 0, -2, 2],和 target = 0。

满足要求的四元组集合为:
[
  [-1,  0, 0, 1],
  [-2, -1, 1, 2],
  [-2,  0, 0, 2]
]
class Solution {
public:
    vector> fourSum(vector& nums, int target) {
        sort(nums.begin(),nums.end());
        vector > res;
        for(int i = 0; i + 3 < nums.size(); ++i)
        {
            if(i > 0 && nums[i] == nums[i-1])   continue;
            for(int j = i+1; j + 2 < nums.size(); ++j)
            {
                if(j > i+1 && nums[j] == nums[j-1])   continue; 
                //此处不能为j>0,循环至少进行一轮后才能continue,确保当前情况的数字组合已经判断过
                int ttarget = target - nums[i] - nums[j] ;
                int l = j+1, r = nums.size()-1;
                while(l < r)
                {
                    int sum = nums[l] + nums[r];        //注意-号
                    if(ttarget == sum)
                    {
                        res.push_back({nums[i],nums[j],nums[l],nums[r]});
                        l++;
                        r--;
                        while(l < r && nums[l] == nums[l-1])    l++;
                        while(l < r && nums[r] == nums[r+1])    r--;
                    }
                    if(ttarget > sum)    l++;
                    if(ttarget < sum)    r--;
                } 
            }
        }
        return res;
    }
};

作者:zrita
链接:https://leetcode-cn.com/problems/4sum/solution/c-z-by-zrita-17/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

19. 删除链表的倒数第N个节点

难度中等983

给定一个链表,删除链表的倒数第 个节点,并且返回链表的头结点。

示例:

给定一个链表: 1->2->3->4->5, 和 n = 2.

当删除了倒数第二个节点后,链表变为 1->2->3->5.

说明:

给定的 n 保证是有效的。

进阶:

你能尝试使用一趟扫描实现吗?

//一次遍历的答案就是  
                        快慢指针~!


class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode* ans=new ListNode(0);
        ans->next=head;
        ListNode* first=ans;
        ListNode* second=ans;
        for(int i=0;i<=n;i++){
            first=first->next;
        }
        //second->0->1...   first->2
        while(first!=NULL){
            first=first->next;
            second=second->next;
        }
        second->next=second->next->next;
        return ans->next;
    }
};

 

20. 有效的括号

难度简单1846

给定一个只包括 '('')''{''}''['']' 的字符串,判断字符串是否有效。

有效字符串需满足:

  1. 左括号必须用相同类型的右括号闭合。
  2. 左括号必须以正确的顺序闭合。

注意空字符串可被认为是有效字符串。

示例 1:

输入: "()"
输出: true

示例 2:

输入: "()[]{}"
输出: true

示例 3:

输入: "(]"
输出: false

示例 4:

输入: "([)]"
输出: false

示例 5:

输入: "{[]}"
输出: true
class Solution {
public:
    bool isValid(string s) {
        stack st;
        if(s.length()==0) return true;
        st.push(s[0]);
        for(int i=1;i

 

 

 

 

 

 

 

你可能感兴趣的:(LeetCode面试题)