FightCrap's blog

Welcome to FightCrap's bolg


  • 首页

  • 归档

  • 标签

  • 分类

LeetCode集锦(十七) - 第69题 Sqrt(X)

发表于 2019-06-07 | 分类于 算法 |

问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Implement int sqrt(int x). 

Compute and return the square root of x, where x is guaranteed to be a non-negative integer.

Since the return type is an integer, the decimal digits are truncated and only the integer part of the result is returned.

Example 1:


Input: 4
Output: 2


Example 2:


Input: 8
Output: 2
Explanation: The square root of 8 is 2.82842..., and since
  the decimal part is truncated, 2 is returned.

翻译:

实现int sqrt(int x)。
计算并返回x的平方根,其中x保证是一个非负整数。
由于返回类型是整数,因此将截断小数,只返回结果的整数部分。
示例1:
输入:4
输出:2
示例2:
输入:8
输出:2
说明:8的平方根是2.82842…,自
小数部分被截断,返回2。


解题思路

本题是找一个数是当前数的平方根,如果是小数,则返回舍弃小数的值。我们可以用遍历的方式,来判断是不是,当时这边需要考虑一下越界的问题,其实也可以不关注,毕竟可以得出越界的上限的平方根是多少,就可以避免这个问题。除了遍历,我们也可以用java自带的Math类来解决,是最简单的。除此之外,本题是找值,而且是在特定范围内找一个值,就可以想到是否可以用二分法来简短查询时间。

解题方法

  1. 按照我们的思路来编辑,代码如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    if (x <= 0) {
    return 0;
    }

    for (int i =x/2+1; i>=0; i=i/2) {
    long result = 1L*i * i;
    if (result == x) {
    return i;
    }
    if (result > x) {
    return i - 1;
    }
    }
    return 0;

    时间复杂度: 该方案用了循环m所以f(n)=(n/2)=n;所以O(f(n))=O(n/2),即T(n)=O(n)

    空间复杂度: 该方案使用了没有使用额外空间,所以空间复杂度是O(n)=O(1);

  2. 使用二分法,代码如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    if (x <= 0) {
    return 0;
    }
    int start = 0;
    int end = x;
    while (start <= end) {
    int index = (start + end) / 2;
    long sum = 1L * index * index;
    if (sum > x) {
    end = index - 1;
    } else {
    start = index + 1;
    }
    }
    return end;

    时间复杂度: 该方案用了循环m所以f(n)=(logn)=n;所以O(f(n))=O(logn),即T(n)=O(logn)

    空间复杂度: 该方案使用了没有使用额外空间,所以空间复杂度是O(n)=O(1);

  3. 借用Math类,代码如下

    1
    2
    3
    4
    5
    if (x <= 0) {
    return 0;
    }

    return (int)Math.sqrt(x);

    时间复杂度: 该方案用了循环m所以f(n)=(1)=n;所以O(f(n))=O(1),即T(n)=O(1)

    空间复杂度: 该方案使用了没有使用额外空间,所以空间复杂度是O(n)=O(1);

总结

本题的大致解法如上所诉, 在特地范围内,而且还是有序的,我们自然可以想到二分法来简化遍历,由于这题是需要最近的最小值,所以当end–后,大的值就变成来最小值,刚刚好满足。

LeetCode集锦(十六) - 第67题 Add Binary

发表于 2019-06-07 | 分类于 算法 |

问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Given two binary strings, return their sum (also a binary string). 

The input strings are both non-empty and contains only characters 1 or 0.

Example 1:


Input: a = "11", b = "1"
Output: "100"

Example 2:


Input: a = "1010", b = "1011"
Output: "10101"

翻译:

给定两个二进制字符串,返回它们的和(也是一个二进制字符串)。
输入字符串都是非空的,并且只包含字符1或0。
示例1:
输入:a = “11”, b = “1”
输出:“100”
示例2:
输入:a = “1010”, b = “1011”
输出:“10101”


解题思路

本题是用字符串模拟2精制的加法,就按照逢2进1的方式遍历一遍,如果长度不同,则在把长的覆盖上去。

解题方法

  1. 按照我们的思路来编辑,代码如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    if (a == null || b == null) {
    return a == null ? b : a;
    }
    StringBuilder stringBuilder = new StringBuilder();
    int lenA = a.length() - 1;
    int lenB = b.length() - 1;
    int add = 0;
    while (lenA >= 0 || lenB >= 0 || add > 0) {
    int result = (lenA >= 0 ? a.charAt(lenA) - '0' : 0) + (lenB >= 0 ? b.charAt(lenB) - '0' : 0) + add;
    add = result / 2;
    stringBuilder.append(result % 2);
    lenA--;
    lenB--;
    }

    return stringBuilder.reverse().toString();

    时间复杂度: 该方案用了循环m所以f(n)=(n)=n;所以O(f(n))=O(n),即T(n)=O(n)

    空间复杂度: 该方案使用了没有使用额外空间,所以空间复杂度是O(n)=O(1);

总结

本题的大致解法如上所诉, 之前用StringBuilder的insert方法,发现速度很慢,看了下源码后,它都会移动数组,也就是正常的数组扩容拷贝,所以特别慢,再次就直接用append,然后反转一下,比之前方式要快很多。

LeetCode集锦(十五) - 第69题 Plus One

发表于 2019-06-07 | 分类于 算法 |

问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Given a non-empty array of digits representing a non-negative integer, plus one to the integer. 

The digits are stored such that the most significant digit is at the head of the list, and each element in the array contain a single digit.

You may assume the integer does not contain any leading zero, except the number 0 itself.

Example 1:


Input: [1,2,3]
Output: [1,2,4]
Explanation: The array represents the integer 123.


Example 2:


Input: [4,3,2,1]
Output: [4,3,2,2]
Explanation: The array represents the integer 4321.

翻译:

给定一个非空的数字数组,表示一个非负整数,加上1的整数次方。
这些数字的存储方式是,最有效的数字位于列表的顶部,数组中的每个元素都包含一个数字。
您可以假设整数不包含任何前导零,除了数字0本身。
示例1:
输入:(1、2、3)
输出(1、2、4):
说明:数组表示整数123。
示例2:
输入:[4、3、2、1)
输出:[4、3、2、2]
说明:数组表示整数4321。


解题思路

本题是基于数组后面加1,一般没有什么问题,特别要注意一下如果进位是最大的怎么办,我这边用了额外的数组来扩容这一步操作,同步赋值,如果有进位,则用新的数组。

解题方法

  1. 按照我们的思路来编辑,代码如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    if (digits.length < 1) {
    return digits;
    }
    int len = digits.length;

    int[] result = new int[len];
    int[] result1 = new int[len + 1];
    int add = 1;
    for (int i = len - 1; i >= 0; i--) {
    int temp = add + digits[i];
    add = temp / 10;
    result[i] = temp % 10;
    result1[i + 1] = result[i];
    }
    if (add != 0) {
    result1[0] = add;
    return result1;
    }
    return result;

    时间复杂度: 该方案用了循环m所以f(n)=(n)=n;所以O(f(n))=O(n),即T(n)=O(n)

    空间复杂度: 该方案使用了两个额外数组,所以空间复杂度是O(2n+1)=O(n);

总结

本题的大致解法如上所诉, 我是用了新的数组来替换原来的数组,当然也可以在原来的数组上修改,这样空间会更加小一点。

LeetCode集锦(十四) - 第58题 Length of Last Word

发表于 2019-06-07 | 分类于 算法 |

问题

1
2
3
4
5
6
7
8
9
10
11
Given a string s consists of upper/lower-case alphabets and empty space characters ' ', return the length of last word in the string. 

If the last word does not exist, return 0.

Note: A word is defined as a character sequence consists of non-space characters only.

Example:


Input: "Hello World"
Output: 5

翻译:

给定一个字符串s由大写/小写字母和空空格字符’ ‘组成,返回字符串中最后一个单词的长度。
如果最后一个单词不存在,返回0。
注意:单词被定义为由非空格字符组成的字符序列。
例子:
输入:“Hello World”
输出:5
给定整数数组号,找到具有最大和的相邻子数组(至少包含一个数字)并返回其和。


解题思路

本题是很简单,我们只要遍历字符,统计不为空字符的字数,遇到空字符则重新计数,并记录上一次操作的数量,如果下一次为空串,则沿用上一次的结果。当然可以直接用string的方法来实现。

解题方法

  1. 按照我们的思路来编辑,代码如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    if (s == null || "".equals(s)) {
    return 0;
    }
    int count = 0;
    int lastCount = count;
    for (int i = 0; i < s.length(); i++) {
    if (s.charAt(i) == ' ') {
    lastCount = count == 0 ? lastCount : count;
    count = 0;
    continue;
    }
    count++;
    }
    return count == 0 ? lastCount : count;

    时间复杂度: 该方案用了循环m所以f(n)=(n)=n;所以O(f(n))=O(n),即T(n)=O(n)

    空间复杂度: 该方案没有使用额外的空间,所以空间复杂度是O(1);

  2. 借用String的方法,代码如下

    1
    2
    3
    4
    5
    6
    if (s == null || "".equals(s)) {
    return 0;
    }
    s = s.trim();

    return s.length() - s.lastIndexOf(" ") - 1;

    时间复杂度: 该方案用了循环m所以f(n)=(n)=n;所以O(f(n))=O(n),即T(n)=O(n)

    空间复杂度: 该方案没有使用额外的空间,所以空间复杂度是O(1);

总结

本题的大致解法如上所诉,内容很简单,只要获取最后一个非空串的字符长度,特别要注意最后全是空字符的情况,那么是往前沿哦。

LeetCode集锦(十三) - 第53题 Maximum Subarray

发表于 2019-06-07 | 分类于 算法 |

问题

1
2
3
4
5
6
7
8
9
10
11
12
13
Given an integer array nums, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum. 

Example:


Input: [-2,1,-3,4,-1,2,1,-5,4],
Output: 6
Explanation: [4,-1,2,1] has the largest sum = 6.


Follow up:

If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.

翻译:

给定整数数组号,找到具有最大和的相邻子数组(至少包含一个数字)并返回其和。
例子:
输入:[2,1,3、4、1、2、1、5、4],
输出:6
说明:[4,-1,2,1]的和最大= 6。
跟进:
如果您已经找到了O(n)的解决方案,那么尝试使用分治方法编写另一个解决方案,这种方法更加微妙。


解题思路

本题是找寻最大值,我们第一想到的方式是遍历,一个个的加过去,判断出现的最大值是多少,当然这个不失为一种方式,但是换个角度想,加上正数肯定是越来越大的,加上负数是越来越小,如果加上一个负数,都比当前值要小了,那么就没有必要在加了,可以把累加值替换为当前值了,这样就不需要重头遍历判断了。所以按照这样子想,是否可以一次遍历就解决呢?

解题方法

  1. 按照我们的思路来编辑,代码如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    if (nums.length < 1) {
    return 0;
    }

    int max = nums[0];
    int sum = max;
    for (int i = 1; i < nums.length; i++) {
    sum=sum + nums[i] < nums[i]?nums[i]:sum + nums[i];
    max=Math.max(sum,max);
    }
    return max;

    时间复杂度: 该方案用了循环m所以f(n)=(n)=n;所以O(f(n))=O(n),即T(n)=O(n)

    空间复杂度: 该方案没有使用额外的空间,所以空间复杂度是O(1);

总结

本题的大致解法如上所诉,本题只想到了一种方法,抛开遍历,只用了这一种方法,但是是否可以分治法来解决,貌似不太想得到。

LeetCode集锦(十二) - 第38题 Count and Say

发表于 2019-06-07 | 分类于 算法 |

问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
The count-and-say sequence is the sequence of integers with the first five terms as following: 


1. 1
2. 11
3. 21
4. 1211
5. 111221


1 is read off as "one 1" or 11.
11 is read off as "two 1s" or 21.
21 is read off as "one 2, then one 1" or 1211.

Given an integer n where 1 ≤ n ≤ 30, generate the nth term of the count-and-say sequence.

Note: Each term of the sequence of integers will be represented as a string.



Example 1:


Input: 1
Output: "1"


Example 2:

Input: 4
Output: "1211"

翻译:

count-and-say序列是前五项为整数的序列:
1 1
2 11
3 21
4 1211
5 111221
1被读作“一个 1”或“11”。
11被读作“两个1”或21。
21被读作“1个2,然后1个1”或1211。
给定一个整数n,其中1≤n≤30,生成count-and-say序列的第n项。
注意:整数序列的每一项都表示为字符串。
示例1:
输入:1
输出:“1”
示例2:
输入:4
输出:“1211”


解题思路

本题其实很简单,但是题目理解上可能不一样,本人一开始没有理解题意,看了下别人的解释才最终明白。本题主要是一个统计和说两个概念,按照我们正常习惯从左往右数和说,比如“1”,我们统计1的个数为1,所以count-and-say格式,第二层就是“11”,也就是一个1的意思,对应“11”而言,我们统计的1的个数为2,按照count-and-say格式,就是“21”,也就是第三层答案,2个1的意思。同理“21”,就是1个2,1个1,所以就是“1211”。本题的解题思路也是如此。

解题方法

  1. 按照我们的思路来编辑,代码如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    String first = "1";
    if (n <= 1) {
    return first;
    }

    StringBuilder stringBuilder = new StringBuilder(first);
    for (int i = 1; i < n; i++) {
    StringBuilder stringBuilder1 = new StringBuilder();
    char pre = stringBuilder.charAt(0);
    int count = 1;
    for (int m = 1; m < stringBuilder.length(); m++) {
    if (stringBuilder.charAt(m) != pre) {
    stringBuilder1.append(count).append(pre);
    pre = stringBuilder.charAt(m);
    count = 1;
    continue;
    }
    count++;
    }
    stringBuilder1.append(count).append(pre);
    stringBuilder = stringBuilder1;

    }

    return stringBuilder.toString();

    时间复杂度: 该方案用了循环,循环层数为2,即T(n)=O(n^2)

    空间复杂度: 该方案没有使用额外的空间,所以空间复杂度是O(1);

总结

本题的大致解法如上所诉,了解题意还是很重要的。

LeetCode集锦(十一) -第35题 Search Insert Position

发表于 2019-06-07 | 分类于 算法 |

问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order. 

You may assume no duplicates in the array.

Example 1:


Input: [1,3,5,6], 5
Output: 2


Example 2:


Input: [1,3,5,6], 2
Output: 1


Example 3:


Input: [1,3,5,6], 7
Output: 4


Example 4:


Input: [1,3,5,6], 0
Output: 0

翻译:

给定一个排序数组和一个目标值,如果找到目标,返回索引。如果没有,返回按顺序插入的索引所在的位置。
您可以假定数组中没有重复项。
示例1:
输入:1、3、5、6,5
输出:2
示例2:
输入:(1、3、5、6),2
输出:1
示例3:
输入:1,3,5,6,7
输出:4
示例4:
输入:(1、3、5、6),0
输出:0


解题思路

本题主要是为了找值,如果和目标值相等,就返回下标,如果没有找到,则返回离它最近且小于它的值的下标。本题可以用遍历解决,也可以使用二分法处理。

解题方法

  1. 第一种解体方法,按照我们的思路来编辑,代码如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    if (nums.length < 0) {
    return 0;
    }

    for (int i = 0; i < nums.length; i++) {
    if (nums[i] >= target) {
    return i;
    }
    }
    return nums.length;

    时间复杂度: 该方案用了一层循环,循环度为n,即T(n)=O(n)

    空间复杂度: 该方案并没有使用额外度空间去存储,所以空间复杂度还是O(1);

  2. 第二种解题方法,是使用了二分查找的方式,代码如下:
    public int searchInsert(int[] nums, int target) {

    if (nums.length < 0) {
        return 0;
    }
    
    return serch(nums, 0, nums.length, target);

    }

    private int serch(int[] nums, int start, int end, int target) {

    if (start >= end) {
        return start;
    }
    
    int mod = (start + end) / 2;
    if (nums[mod] == target) {
        return mod;
    }
    if (nums[mod] < target) {
        return serch(nums, mod + 1, end, target);
    }
    
    if (nums[mod] > target) {
        return serch(nums, start, mod, target);
    }
    return 0;

    }

    1
    2
    3
    4
    5
    6
        __时间复杂度__:
    该方案用了递归二分查找,即T(n)=O(nlogn)

    __空间复杂度__:
    该方案并没有使用额外度空间去存储,所以空间复杂度还是O(1);
    3. 第三种解题方案是针对与第二种解题优化的,递归查找在数据量足够大的情况下,性能略差,所以使用循环来解决递归。代码如下:

    if (nums.length < 0) {

        return 0;
    }
    int index = 0;
    int len = nums.length;
    while (index < len) {
        int mod = (index + len) / 2;
        if (nums[mod] == target) {
            return mod;
        } else if (nums[mod] > target) {
            len = mod;
        } else {
            index = mod + 1;
        }
    }
    
    return index;

    ``` 时间复杂度: 该方案用了递归二分查找,即T(n)=O(nlogn)

    空间复杂度: 该方案并没有使用额外度空间去存储,所以空间复杂度还是O(1);

    总结

    本题的大致解法如上所诉,但是可以更改的方式很多,运用循环,二分法来进行对本题的解答。

LeetCode集锦(十) - 第28题 Implement StrStr

发表于 2019-06-07 | 分类于 算法 |

问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Implement strStr().

Return the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.

Example 1:


Input: haystack = "hello", needle = "ll"
Output: 2


Example 2:


Input: haystack = "aaaaa", needle = "bba"
Output: -1


Clarification:

What should we return when needle is an empty string? This is a great question to ask during an interview.

For the purpose of this problem, we will return 0 when needle is an empty string. This is consistent to C's strstr() and Java's indexOf().

翻译:

实现strStr ()。
返回haystack中needle的第一次出现的索引,如果针不是haystack的一部分,返回-1。
示例1:
输入:haystack = “hello”, needle = “ll”
输出:2
示例2:
输入:haystack = “aaaaa”, needle = “bba”
输出:1
澄清:
当needle是空字符串时,我们应该返回什么?这是一个非常适合在面试中问的问题。
对于这个问题,当needle为空字符串时,我们将返回0。这与C的strstr()和Java的indexOf()一致。


解题思路

本题思路很简单,就是让我们实现java的indexof方法,我们根据循环判断haystack中是否有needle字符就行了,当然,可以直接调用java的api。

解题方法

  1. 第一种解题方法,按照思路编辑,代码如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    if (haystack == null || "".equals(needle)) {
    return 0;
    }
    int len = haystack.length() - needle.length()+1;
    int needLen = needle.length();
    for (int i = 0; i < len; i++) {
    if (haystack.charAt(i) != needle.charAt(0)) {
    continue;
    }
    int m;
    for (m = 1; m < needle.length(); m++) {
    if (haystack.charAt(i + m) != needle.charAt(m)) {
    break;
    }
    }

    if (m == needLen) {
    return i;
    }
    }

    return -1;

    时间复杂度: 该方案用了循环,循环层数为2,所以O(f(n))=O(Mn),即T(n)=O(n^2)

    空间复杂度: 该方案没有使用额外的空间,所以空间复杂度是O(1);

  2. 第二种解题方法,直接调用api,简单粗暴(当然这个是不符合要求的),代码如下

    1
    2
    3
    4
    5
    6
        
    if (haystack == null ) {
    return 0;
    }

    return haystack.indexOf(needle);

    时间复杂度: 该方案T(n)=O(1)

    空间复杂度: 该方案没有使用额外的空间,所以空间复杂度是O(1);

总结

本题的大致解法如上所诉,本题只想到了一种方法,第二种方法是不符合要求的,偷懒专用,毕竟都选用了的语言,语言自带的不用白不用

LeetCode集锦(九) - 第27题 Remove Element

发表于 2019-06-07 | 分类于 算法 |

问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
Given an array nums and a value val, remove all instances of that value in-place and return the new length. 

Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory.

The order of elements can be changed. It doesn't matter what you leave beyond the new length.

Example 1:


Given nums = [3,2,2,3], val = 3,

Your function should return length = 2, with the first two elements of nums being 2.

It doesn't matter what you leave beyond the returned length.


Example 2:


Given nums = [0,1,2,2,3,0,4,2], val = 2,

Your function should return length = 5, with the first five elements of nums containing 0, 1, 3, 0, and 4.

Note that the order of those five elements can be arbitrary.

It doesn't matter what values are set beyond the returned length.

Clarification:

Confused why the returned value is an integer but your answer is an array?

Note that the input array is passed in by reference, which means modification to the input array will be known to the caller as well.

Internally you can think of this:


// nums is passed in by reference. (i.e., without making a copy)
int len = removeElement(nums, val);

// any modification to nums in your function would be known by the caller.
// using the length returned by your function, it prints the first len elements.
for (int i = 0; i < len; i++) {
    print(nums[i]);
}

翻译:

给定数组号和值val,删除该值的所有实例并返回新的长度。
不要为另一个数组分配额外的空间,您必须使用O(1)额外内存修改输入数组。
元素的顺序可以改变。在新的长度之外留下什么并不重要。
示例1:
给定nums = [3,2,2,3], val = 3,
函数应该返回length = 2, nums的前两个元素为2。
在返回长度之外留下什么并不重要。
示例2:
给定nums = [0,1,2,2,3,0,4,2], val = 2,
函数应该返回length = 5, nums的前五个元素包含0、1、3、0和4。
注意,这五个元素的顺序可以是任意的。
在返回长度之外设置什么值并不重要。
澄清:
为什么返回的值是整数而您的答案是数组?
注意,输入数组是通过引用传入的,这意味着调用者也知道对输入数组的修改。
你可以这样想:
// nums是通过引用传入的。(即。,无须复印)
int len = removeElement(nums, val);
//函数中对nums的任何修改都会被调用者知道。
//使用函数返回的长度,它输出第一个len元素。
for (int i = 0;i<len;i++){
print (num[i]);
}


解题思路

本题思路很简单,该题和第26题很相似,这边是移除了指定的相同数字,而且本题对顺序没有要求,那么我们可以通过遍历,把相同的数据放到后面,返回非指定数字的数量就可以了

解题方法

  1. 按照我们的思路来编辑,代码如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    int index = 0;
    int len = nums.length;
    for (int i = 0; i < len - index; i++) {
    if (nums[i] != val) {
    continue;
    }

    int temp = len - 1 - index;
    nums[i] = nums[i] ^ nums[temp];
    nums[temp] = nums[temp] ^ nums[i];
    nums[i] = nums[temp] ^ nums[i];
    i--;
    index++;
    }

    return len - index;

    时间复杂度: 该方案用了循环,循环层数为1;所以O(f(n))=O(n),即T(n)=O(n)

    空间复杂度: 该方案没有使用额外的空间,所以空间复杂度是O(1);

总结

本题的大致解法如上所诉,本题本人无法想到优化的方式,只是利用了位运算来简化了换位的方式。

LeetCode集锦(八) - 第26题 Remove Duplicates From Sorted Array

发表于 2019-06-07 | 分类于 算法 |

问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
Given a sorted array nums, remove the duplicates in-place such that each element appear only once and return the new length. 

Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory.

Example 1:


Given nums = [1,1,2],

Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively.

It doesn't matter what you leave beyond the returned length.

Example 2:


Given nums = [0,0,1,1,1,2,2,3,3,4],

Your function should return length = 5, with the first five elements of nums being modified to 0, 1, 2, 3, and 4 respectively.

It doesn't matter what values are set beyond the returned length.


Clarification:

Confused why the returned value is an integer but your answer is an array?

Note that the input array is passed in by reference, which means modification to the input array will be known to the caller as well.

Internally you can think of this:


// nums is passed in by reference. (i.e., without making a copy)
int len = removeDuplicates(nums);

// any modification to nums in your function would be known by the caller.
// using the length returned by your function, it prints the first len elements.
for (int i = 0; i < len; i++) {
    print(nums[i]);
}

翻译:

给定一个已排序的数组号,删除重复项,使每个元素只出现一次,并返回新的长度。
不要为另一个数组分配额外的空间,您必须使用O(1)额外内存修改输入数组。
示例1:
给定nums = [1,1,2],
函数应该返回length = 2, nums的前两个元素分别为1和2。
在返回长度之外留下什么并不重要。
示例2:
给定nums = [0,0,1,1,1,2,2,3,3,4],
函数应该返回length = 5, nums的前五个元素分别修改为0、1、2、3和4。
在返回长度之外设置什么值并不重要。
澄清:
为什么返回的值是整数而您的答案是数组?
注意,输入数组是通过引用传入的,这意味着调用者也知道对输入数组的修改。
你可以这样想:
// nums是通过引用传入的。(即。,无须复印)
int len = removeduplicate (nums);
//函数中对nums的任何修改都会被调用者知道。
//使用函数返回的长度,它输出第一个len元素。
for (int i = 0;i<len;i++){
print (num[i]);
}


解题思路

本题思路很简单,要求我们使用O(1)的空间,也就是我们只能在当前数组上操作,由题目可知,数组是排序的,所以只要遍历一次,把不重复的往前面放,那么最前面的就是我们需要的结果。

解题方法

  1. 按照我们的思路来编辑,代码如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    if (nums.length <= 1) {
    return nums.length;
    }
    int number = 0;

    for (int i = 1; i < nums.length; i++) {
    if (nums[i] > nums[number]) {
    number++;
    nums[number] = nums[i];
    }
    }

    return number + 1;

    时间复杂度: 该方案用了循环,循环层数为1,即T(n)=O(n)

    空间复杂度: 该方案没有使用额外的空间,所以空间复杂度是O(1);

总结

本题的大致解法如上所诉,本题只想到了一种方法,直接按照思路编写

1234
FightCrap

FightCrap

制造bug的永动机

37 日志
2 分类
2 标签
GitHub E-Mail
© 2019 FightCrap
由 Hexo 强力驱动
|
主题 — NexT.Mist v5.1.4