leetcode题目总结 1,3,4,5,9,20,26,27,28,34,41

34. 在排序数组中查找元素的第一个和最后一个位置的思路的菜鸟总结

原题链接:https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/description/

题目描述:

给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。

你的算法时间复杂度必须是 O(log n) 级别。

如果数组中不存在目标值,返回 [-1, -1]

思路:

原本以为只有两组数据测试,没有更多过难的数据测试,放松了警惕,两组数据如下:

示例 1:输入: nums = [5,7,7,8,8,10], target = 8 输出: [3,4]

示例 2:输入: nums = [5,7,7,8,8,10], target = 6 输出: [-1,-1]

对应代码只有:

for(int i=0;i

但是随着提交错误的产生,我越发知道自己的错误在哪:

首先,我没有考虑数组为零的情况,而且审题不清,题目要求是不存在目标数值则返回【-1,-1】,我却擅自返回了【0】

if(nums.size()==0) return a;

再者,我没有考虑到【1】,1的数据情况,此时应该返回【0,0】,代码如下:

if(nums.size()==1){
            if(nums[0]==target) {
                a[0]=a[1]=0;
                return a;

最后还有一点,我没有在if(nums.size()==1) 分支语句下判断与目标值不同的情况,下面是改正后的分支语句:
 

 else if(nums.size()==1){
            if(nums[0]==target) {
                a[0]=a[1]=0;
                return a;
            }
            else return a;
        }

最后考虑,其实可以使用switch语句来做这个题目,这样可以减少代码量。

源代码:

class Solution {
public:
    vector searchRange(vector& nums, int target) {
        int k=0;
        vectora(2,-1);
        if(nums.size()==0) return a;
        else if(nums.size()==1){
            if(nums[0]==target) {
                a[0]=a[1]=0;
                return a;
            }
            else return a;
        }
        else{
            for(int i=0;i

 

 

27. 移除元素的简单思路与26删除数组的重复项的简单思路

27原题链接:https://leetcode-cn.com/problems/remove-element/description/

26原题链接:https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array/description/

27题目描述:

给定一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,返回移除后数组的新长度。

不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。

元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

26题目描述:

给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。

不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。

分析:需要把握的点在原地修改元素和数组的长度,降低难度的点是不需要考虑新长度后面的元素。、

思路:

使用 O(1) 额外空间的条件下完成,则最好利用循环语句从数组顶部往数组底部靠拢,这样更容易来确定数组的长度,另外还需设置多余的变量来确定删除的元素个数,我这里用k来确定删除的个数。如下:

第一个和第二个循环语句:
 

for(int i=nums.size()-1;i>=0;i--)
 for(int j=i;j

27判断数组中与寻找的变量相同,则k加一:
 

if(nums[i]==val) {
                    k++;

26判断重复项,则k加一:

if(nums[i]==nums[i-1]){
                k++;

27源代码如下:
 

class Solution {
public:
 int removeElement(vector& nums, int val) {
    int k=0;
        for(int i=nums.size()-1;i>=0;i--){
            if(nums[i]==val) {
                    k++;
                 for(int j=i;j

26源代码如下:

class Solution {
public:
    int removeDuplicates(vector& nums) {
        int k=0;
        for(int i=nums.size()-1;i>0;i--){
            if(nums[i]==nums[i-1]){
                k++;
                for(int j=i;j<=nums.size()-k;j++){
                    nums[j-1]=nums[j];
                }
            }
        }
        return nums.size()-k;
    }
};

 

 

5. 最长回文子串的简单思路

原题链接:https://leetcode-cn.com/problems/longest-palindromic-substring/description/

题目描述:

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为1000。

源代码:

class Solution {
public:
    string longestPalindrome(string s) {
        if(s.empty()) return s;
        string res;
        for(int i=0;ires.size()) res=t;
            t=Palindrome(s,i,i+1);
            if(t.size()>res.size()) res=t;
        }
        return res;
    }
    string Palindrome(string &s1,int l,int r){
        while(l>=0&&r

 

思路:

考虑奇偶,设置两个判断语句。在另一个函数体中判断是否回文并返回长度,另外考虑到特殊情况。

利用到一个函数

     return s1.substr(l+1, r-l-1);

复制指定长度的字符串。

 

 

3. 无重复字符的最长子串的Java方法

题目链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/description/

题目描述:

给定一个字符串,找出不含有重复字符的最长子串的长度。

错误的c++源代码:

1.

class Solution {
public:
    int first,i,j;
    int lengthOfLongestSubstring(string s) {
        if(s.empty()) return 0;
        if(s.length()==1) return 1;
        for(i=0;i0) break;
         }
         if(t==0){
           int k=y-x;
            if(longest

2.

class Solution {
public:
    int first,i,j;
    int lengthOfLongestSubstring(string s) {
        if(s.empty()) return 0;
        if(s.length()==1) return 1;
        for(i=0;i

总结:

自己忙了一天,还是没什么好结果,最接近正确答案是下图:

leetcode题目总结 1,3,4,5,9,20,26,27,28,34,41_第1张图片

真的是崩溃,不过在这里面的错误也让我惊醒:

1.利用好循环语句,尤其是遍历类的循环,加上条件判断语句后更加要注重遍历循环语句。

2.善于利用bool类型,不要再另外一个函数体类return。

关于Java的学习:

public class Solution {
    public int lengthOfLongestSubstring(String s) {
        int n = s.length();
        Set set = new HashSet<>();
        int ans = 0, i = 0, j = 0;
        while (i < n && j < n) {
            // try to extend the range [i, j]
            if (!set.contains(s.charAt(j))){
                set.add(s.charAt(j++));
                ans = Math.max(ans, j - i);
            }
            else {
                set.remove(s.charAt(i++));
            }
        }
        return ans;
    }
}

该代码是参考:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/solution/

 

我觉得很重要的一些知识点:

1.一些妙用的函数:

HashSet 
Set set = new HashSet<>()
set.contains()
set.add()
set.remove()
 Math.max(ans, j - i);

2.要善于利用不同语言间的优势,虽然现在没学Java,但是自己事先尝到了有一些语言的对一些题目的针对性很强,以后要多多注意。

 

 

9. 回文数的简单思路

原题链接:https://leetcode-cn.com/problems/palindrome-number/description/

题目描述:判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。

进阶:

你能不将整数转为字符串来解决这个问题吗?

源代码:

class Solution {
public:
    bool isPalindrome(int x) {
        if(x<0||(x%10==0&&x!=0))
            return false;
        int temp=0;
        while(x>temp){
            temp=temp*10+x%10;
            x/=10;
        }
        return temp==x||temp/10==x;
    }
};

思路:

这种题目事先曾做过,此时再做算是温故知新,循环语句中X/=10这个语句没注意浪费了一些时间,看了一下阅读解答里面的解题思想,不用完全转换成数,只要转换一半即可,缩短了时间,虽然时间复杂度还不懂,但接触多了,想必会有些感悟

题目比较简单想到的方法是可以将数字直接转换成字符串,详情可以看https://blog.csdn.net/michaelhan3/article/details/75667066/

这种数字转换的方法也能想到,只是不能调用系统的函数,比较麻烦些。

 

 

4. 两个排序数组的中位数的简单思路

原题链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays/description/

题目描述:

给定两个大小为 m 和 n 的有序数组 nums1 和 nums2 

请找出这两个有序数组的中位数。要求算法的时间复杂度为 O(log (m+n)) 。

你可以假设 nums1nums2 均不为空。

源代码:

class Solution {
public:
    double findMedianSortedArrays(vector& nums1, vector& nums2) {
    vectora(nums1.size()+nums2.size(),NULL);
        for(int i=0;i

思路:

把两个有序数组暴力组合在一起,进行排序后简单地进行寻找中位数。

1.自己不知道时间、空间复杂度的意思。

2.这个题目原本看到过,但是自己因为排序的麻烦不想去做,看到了sort()的用法,觉得可以尝试,但我觉得时间复杂度应该超过了

3.注意第二个数组赋值到总数组的时候

for(int j=nums1.size();j

4.另设的数组可以有自己的size()。

5.个人认为读代码对我很重要,感觉自己已经晚了很多,但是这种愧疚感弥补不了我读代码不懂得烦躁感,加油吧。

 

 

1. 两数之和的简单想法

题目链接:https://leetcode-cn.com/problems/two-sum/description/

原题描述:

给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。

你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用。

源代码:

class Solution {
public:
    vector twoSum(vector& nums, int target) {
        vectora(2,0);
            for(int i=0;i=0||nums[i])
                for(int j=i+1;j

简单思路:

原本思考可以有先确定第一个加数再确定第二个加数的方法,不过我的考虑只停留在了正数方面,结果数据告诉我负数的情况就很纳闷,看到提示后用了暴力解答的方法,时间复杂度较高。

 

 

20. 有效的括号的简单想法

题目链接:

https://leetcode-cn.com/problems/valid-parentheses/description/

题目描述:

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

有效字符串需满足:

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

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

思路:

原本是想先判断括号的数量是否契合,然后利用替换的方法来进行,但太麻烦最后选择放弃(主要还是懒),于是参考了一下别人的代码,发现栈的思想非常重要,简直是算这种题目的利器。

栈的应用:

stack cs;
cs.push(c);
cs.empty();
cs.top();
cs.pop();

 注意一下细节,不要怕代码长度太长,主要是有思路能简化就好。

源代码:

class Solution {
public:
    bool isValid(string s) {
	stack cs;
	char c;
    int i=0;
	while (i

 

 

 

41. 缺失的第一个正数的简单思路

题目链接:

https://leetcode-cn.com/problems/first-missing-positive/description/

题目描述:

给定一个未排序的整数数组,找出其中没有出现的最小的正整数。

思路:

一开始以为比较简单,没有把负数去掉的情况考虑进去,结果靠一次次数据把我敲醒。

后来整体的思路是:先选择排序,再考虑正整数的数据,考虑正整数数据没有和只有一个的情况,再考虑最小整数出现在正整数中间位置的情况,最后考虑最小整数比最大的数组整数都大的情况,情况考虑的比较多,得考虑到比较刁钻得数据。

选择排序:

int k,f,m,n=0;
        if(nums.size()==0) return 1;
        for(int i=0;inums[j]) k=j;
                f=nums[k];
                nums[k]=nums[i];
                nums[i]=f;
        }

考虑正整数在数组中的位置,如果都是正整数则重置为零:

for(;n0) {
                n++;
                break;
            }
        }
        if(nums[0]>=0) n=0;

最后是考虑一个和多个排序好的正整数的情况:

f(nums.size()-n==1) {
            if(nums[n]==1) return 2;
            else return 1;
        }
        if(nums[n]>1) return 1;
        for(m=n;m1) return nums[m]+1;
        return nums[m-1]+1;

    }

源代码:

class Solution {
public:
    int firstMissingPositive(vector& nums) {
        int k,f,m,n=0;
        if(nums.size()==0) return 1;
        for(int i=0;inums[j]) k=j;
                f=nums[k];
                nums[k]=nums[i];
                nums[i]=f;
        }
       
        for(;n0) {
                n++;
                break;
            }
        }
        if(nums[0]>=0) n=0;
        if(nums.size()-n==1) {
            if(nums[n]==1) return 2;
            else return 1;
        }
        if(nums[n]>1) return 1;
        for(m=n;m1) return nums[m]+1;
        return nums[m-1]+1;

    }
};

 

 

28. 实现strStr()的简单思路

原题目的链接:https://leetcode-cn.com/problems/implement-strstr/description/

题目描述:

给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回  -1

细节:

当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。

对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与C语言的 strstr() 以及 Java的 indexOf() 定义相符。

想法:

首先,应该把特殊情况用if语句率先解决:

if(haystack.empty() && needle.empty()) return 0;
        if(haystack.empty()) return -1;
        if(needle.empty()) return 0;
        if(haystack.size()

然后考虑怎么能让检索更为简便且快捷,排除之前的状况,考虑到 needle的长度一定会小于额度长度,我们可以利用双重循环和两者之间的差值长度来简化运行效率:

for(int i=0;i

双重循环的优势在基本的几个排序算法(冒泡排序、选择排序等)中显露无疑,在这里利用双重循环适合检索和确认needle和haystack重复部分

以下是源代码:

class Solution {
public:
    int strStr(string haystack, string needle) {
        if(haystack.empty() && needle.empty()) return 0;
        if(haystack.empty()) return -1;
        if(needle.empty()) return 0;
        if(haystack.size()

 

总结:  自我感觉要多阅读优秀代码,多考虑题目的边界问题,掌握一些基本的技能。

你可能感兴趣的:(leetcode题目总结 1,3,4,5,9,20,26,27,28,34,41)