LeetCode题解精选(一)

简单(Easy):

1 - 哈希表(恒定时间查找)并且一次遍历在进行迭代并将元素插入到表中的同时,我们还会回过头来检查表中是否已经存在当前元素所对应的目标元素。如果它存在,那我们已经找到了对应解,并立即将其返回。(官方题解就挺好)感觉似乎需要多重循环查找和比较数的情况,都可以用hashmap在第一重遍历的时候就将相应的数插入表中来降低时间复杂度
 
 

7-整数反转 :主要是整数溢出的判断,官方的方法就是硬记住-2^31 和 2^31-1 的个位数,但是这篇题解很巧妙,先用long去存储,再判断强制转换为int后与原数是否相同。
 
 

9-回文: 官方给的依旧优雅,为了防止溢出选择转一半的方法,重点在于如何判断到一半了。不过…值得注意的是,回文数必定不会溢出,所以溢出的情况(不等)就自然归到false里了。也就是说无需考虑溢出问题…😥

//不过验证溢出可以这样写一句:cur是当前反转后的值
if (cur > INT_MAX / 10) return false;

 
 

13-罗马数字:取巧的做法就是构建哈希表,把特殊情况全部列出,然后关键就是看一次取一个字符还是两个。常规做法:除了两行python那个不能看,其他高赞解答都很清晰…
 
 

14-最长公共前缀:一开始不熟悉常见的内置函数,不知道该用啥,现在总结一下:

str.substring(0,i) : 切割字符串
str.indexOf(String ) : 返回str中String第一次出现的索引,没有返回-1
str.charAt(i) : 字符串str中i处的字符
str.equals("") : 字符串判等
注意:
数组.length     字符串.length()  //一个属性,一个是方法

还有就是,循环里常常都是跳出循环的情况而非继续的情况,所以对应于该题就是相应位的字符不等或者有某个字符串走到头了(官方解答的算法二:水平扫描更好理解)

 
 
20-有效的括号:显然是用栈,思路很简单

java栈的方法:        
Stack<Character> stack = new Stack<>();
pop()peek()push()
注意栈空的情况
"不过python实现栈真的舒服...代码简洁,直接上数组就是栈,调用append、pop方法,读取栈顶就是stack[-1]"
// 提供一个栈的比较好的思路,不用map存储
public boolean isValid(String s) {
        if(s.isEmpty())
            return true;
        Stack<Character> stack=new Stack<Character>();
        for(char c:s.toCharArray()){
            if(c=='(')
                stack.push(')');
            else if(c=='{')
                stack.push('}');
            else if(c=='[')
                stack.push(']');
            else if(stack.empty()||c!=stack.pop())
                return false;
        }
        if(stack.empty())
            return true;
        return false;
    }
# python写法
class Solution:
    def isValid(self, s: str) -> bool:
        dic = {'{': '}',  '[': ']', '(': ')', '?': '?'}
        stack = ['?']
        for c in s:
            if c in dic: stack.append(c)
            elif dic[stack.pop()] != c: return False 
        return len(stack) == 1

作者:jyd
链接:https://leetcode-cn.com/problems/valid-parentheses/solution/valid-parentheses-fu-zhu-zhan-fa-by-jin407891080/

 
 
21-合并链表: 常规套路迭代,不过总有大神秀的一匹四行斩杀😱…我还是老老实实按官方方法做吧www(有一点就是使用哨兵节点记录头,不过这个过程不必要,可以看我这个链接的处理方法)
 
 

26-删除排序数组:双指针的典型应用,官方题解很详细
 
 

27-移除元素:害是双指针…就是迭代时双指针怎么走不太好想,感觉有点反常规。

// c++另解:不知道效率如何
class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        if (nums.size() == 0)
        return 0;

        for (int i = 0; i < nums.size(); i++) {
            if (nums[i] == val) {
                nums.erase(nums.begin() + i);
                i--;
            }
        }

        return nums.size();

    }
};

28-实现strStr() : 滑动窗口 + substring方法(还有优化的算法,不过这样解已经可以0ms完成运行…)
 
 

35-搜索插入位置:典型二分法,注意边界条件
 
 

53-最大子序列和 :dp问题,不过无需一个dp数组存储状态,因为最大值只与前一个状态有关,所以O(n)的空间可以优化。
 
 

58-最后一个单词的长度 :关键在于想到末尾有多余的空格先除去以及双指针做差得长度的方法。值得注意的是在数组/字符串有界的while循环中,一定要判断下标>=0, 否则会数组越界,并且判断的条件一定要写在前面(针对&&,因为判断有顺序,需要前提是不越界)
 
 

67-二进制求和 :这道题官方给的解答并不好,可以底下评论区的方法,重点是
(1)对于N进制数,sum = ( 相应位和 + 进位 )% N, 新进位 = ( 相应位和 + 原进位 )/ N
(2)在频繁改动字符串时用StringBuilder效率明显提高,不过记得最后用toString转为String类型
(3)进制的小题涉及字符串可调用reverse方法或者使用insert(0,number),这样就不会受到顺序的困扰
(4)双指针有一个走到头时让他一直为0的做法也很巧妙,学习到了,下次遇到就可以疯狂对线👍

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值