动态规划

【刷题】LeetCode部分题型技巧

2019-07-17  本文已影响0人  Cesarean

前言

这是用来记录在刷LeetCode时遇到的一些问题的技巧,因只记录一些技巧或优化方案故不一定全部记录,自认为的最佳方案已添加+前缀。另可通过搜索题号查看相关问题。


题表

1】. 两数相加
简要介绍:给定一个数组与一个目标数字,在该数组中寻找两个数,使其和等于目标,返回其下标数组
给定条件:题目必定有解,且每个数至多使用一次

28】. 实现经典的strstr()方法
简要介绍:给定base字符串以及need字符串,要求在前者中找到后者的第一次出现的下标
给定条件:题目不一定有解,找不到时返回-1

class KMPSolution {
    private int[] next(String needle) {
        if (needle.length() <= 0) {
            throw new RuntimeException("KMP does not support empty string.");
        }
        int next[] = new int[needle.length() + 1];
        next[0] = -1;
        for (int i = 0, j = -1; i < needle.length(); ) {
            if (j == -1 || needle.charAt(i) == needle.charAt(j)) {
                ++i;
                ++j;
                next[i] = j;
            } else {
                j = next[j];
            }
        }
        return next;
    }

    public int strStr(String haystack, String needle) {
        if (needle.length() == 0) return 0;
        int[] next = next(needle);
        int i = 0, j = 0;
        while (i < haystack.length() && j < needle.length()) {
            if (j == -1 || haystack.charAt(i) == needle.charAt(j)) {
                ++i;
                ++j;
            } else {
                j = next[j];
            }
        }

        if (j == needle.length()) {
            return i - j;
        }
        return -1;
    }
}
class HashSolution {
    public int strStr(String haystack, String needle) {
        if(needle.length() == 0) return 0;
        if(haystack.length() < needle.length()) return -1;
        int needleHash = 0, hayHash = 0;
        int nl = needle.length(), hl = haystack.length(), del = hl - nl;
        for(int i = 0 ; i < nl ; ++i){
            needleHash += needle.charAt(i);
            hayHash += haystack.charAt(i);
        }
        for(int i = 0 ; i <= del ; ++i){
            if(i != 0){
                hayHash -= haystack.charAt(i - 1);
                hayHash += haystack.charAt(i + nl - 1);
            }
            if(hayHash == needleHash){
                int j = 0;
                for(; j < nl ; ++j){
                    if(haystack.charAt(i+j) != needle.charAt(j)){
                        break;
                    }
                }
                if(j == nl){
                    return i;
                }
            }
        }
        return -1;
    }
}

53】. 最大子数组
简要介绍:给定一个整型数组,要求寻找到和最大的连续子数组,并返回其最大和

69】. 整数平方根
简要介绍:求一个整数的平方根,小数部分截取

public int mySqrt(float x)
{
    final float precision = 0.1f;
    float res = x, pre;
    do
    {
        pre = res;
        res = (res + x/res) / 2;
    }while(Math.abs(res-pre) > precision);
    return (int)res;
}
float Q_rsqrt( float number )
{
    long i;
    float x2, y;
    const float threehalfs = 1.5F;

    x2 = number * 0.5F;
    y   = number;
    i   = * ( long * ) &y;   // evil floating point bit level hacking
    i   = 0x5f3759df - ( i >> 1 ); // what the fuck?
    y   = * ( float * ) &i;
    y   = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration
    // y   = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be removed

    return y;
}  

70】. 爬楼梯
简要介绍:给定一个数字表示有几阶楼梯,并一次只能爬1或者2阶楼梯,求有几种爬法。

136】. 出现一次的数字
简要介绍:给定一个数组,要求找出其中只出现一次的数字
给定条件:其他的出现的数字必定出现两次,出现一次的数字只有一个

141】. 链表环判定
简要介绍:给定一个链表,判断其是否有环

142】. 链表环节点寻找
简要介绍:给定一个链表,判断其是否有环并找出环节点
改进自:【141

155】. 最小栈
简要介绍:设计一个栈,其提供一个方法,能获取当前栈中的最小值

160】. 寻找两个链表第一个交点
简要介绍:给定两条链表,寻找这两条链表的第一个交点,如果不相交则返回null

169】. 最常出现的数
简要介绍:给定一个数组,要求在里面找到出现次数大于数组一半大小的数

203】. 删除链表中的数
简要介绍:给定一个链表以及一个目标数字,要求在里面删除所有值等同于该目标数字的链表节点

  public ListNode removeElements(ListNode head, int val) {
        ListNode node = head, pre = head;
        while (node != null)  node = val == node.val? pre == node ? (head = pre = node.next) : (pre.next = node.next):(pre = node).next;
        return head;
    }

解题与优化方案总结

#】哈希表:将已经遇到过的对象存入哈希表,可进行假设o(1)的时间消耗

#】双指针:诸如链表环判定,倒数第K个节点balabala

#】线性空间优化:在题目所需要的额外空间是线性空间时可进行空间优化

上一篇 下一篇

猜你喜欢

热点阅读