Welcome to the 30-Day LeetCoding Challenge!
由于不平凡的2020疫情影响,全世界大部分人都呆在家里防止感染病毒,于是leecode发起了一个30天代码挑战,从4.1~4.30,下面我将开始挑战!
文章目录
- Welcome to the 30-Day LeetCoding Challenge!
- Problem1: [Single Number](https://leetcode.com/explore/featured/card/30-day-leetcoding-challenge/528/week-1/3283/)
- problem 2: [Happy Number](https://leetcode.com/explore/challenge/card/30-day-leetcoding-challenge/528/week-1/3284/)
- Problem 3: [Maximum Subarray](https://leetcode.com/problems/maximum-subarray/)
- Problem 4: [Move Zeroes](https://leetcode.com/problems/move-zeroes/)
- problems 5:[Best Time to Buy and Sell Stock II](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/)
- problems 6:[Group Anagrams](https://leetcode.com/problems/group-anagrams/)
- problem 7:Counting Elements
Problem1: Single Number
Given a non-empty array of integers, every element appears twice except for one. Find that single one.
Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
Example 1:
Input: [2,2,1]
Output: 1
Example 2:
Input: [4,1,2,1,2]
Output: 4
题意给出一个非空整数数组,里面的元素除了一个只出现一次外,其他的元素都出现了两次,让找出那个只出现了一次的元素。
题目让给出一个O(n)的算法,并且空间复杂度为O(1)。
solution1: 首先不考虑题目给的限制,可以用C++的集合set来做(利用set不允许出现重复元素的特点),即遍历这个数组,如果set里面没有这个元素,则插入,如果有这个元素,则把这个元素删掉然后继续遍历,最后就会只剩下只出现一次的那个元素。
Mycode1:
class Solution {
public:
int singleNumber(vector<int>& nums) {
set<int> st;
st.clear();
for(int i = 0; i < nums.size(); i++){
if (st.count(nums[i])){//判断nums[i]是否出现过
st.erase(nums[i]);
}
else{
st.insert(nums[i]);
}
}
return *st.begin();
}
};
solution2: 这道题可以用逻辑异或来做。
这里说一下异或的重要性质:
- 交换律:a ^ b = b ^ a
- 结合律:(a ^ b) ^ c = a ^ (b ^ c)
- 对于任何数x,都有x ^ x = 0, x ^ 0 = x
- 自反性:A ^ B ^ B = A ^ 0 = A
既然相同的数异或是0,0和任何数异或后等于该数本身,我们就可以直接把题目所给的数组里的每一个元素都异或起来,最终的结果就是那个唯一的只出现一次的数了。
Mycode2:
class Solution {
public:
int singleNumber(vector<int>& nums) {
int ans = 0;
for(int i = 0; i < nums.size(); i++)
ans^=nums[i];
return ans;
}
};
problem 2: Happy Number
Write an algorithm to determine if a number
n
is “happy”.
A happy number is a number defined by the following process: Starting with any positive >integer, replace the number by the sum of the squares of its digits, and repeat the process until >the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include >1. Those numbers for which this process ends in 1 are happy numbers.
Return True ifn
is a happy number, and False if not.
Example:
Input: 19 Output: true Explanation: 1^2 + 9^2 = 82 8^2 + 2^2 = 68 6^2 + 8^2 = 100 1^2 + 0^2 + 0^2 = 1
这道题直接模拟即可,要思考下什么样的数不是happy number,那就是模拟过程中会重复出现的数,例如一个数模拟过程中出现了一个a,模拟半天后又出现了a,这样就进入了死循环,就不可能是happy number。可以用set记录出现的数,如果重复出现直接跳出循环。
Mycode:
class Solution {
public:
bool isHappy(int n){
set<int> st;
while(n != 1){
int sum = 0;
while(n){
sum += (n % 10)*(n % 10);
n /= 10;
}
n = sum;
//如果st里面出现过这个数,则说明发生死循环了
if (st.count(n)) break;
st.insert(n);
}
return n == 1;
}
};
Problem 3: Maximum Subarray
Problem 4: Move Zeroes
Given an array nums, write a function to move all 0’s to the end of it while maintaining the relative order of the non-zero elements.
Example:Input: [0,1,0,3,12] Output: [1,3,12,0,0]
Note:
- You must do this in-place without making a copy of the array.
- Minimize the total number of operations.
这道题的题意很简单,就是把一个数组里面的0全部移动到数组的尾部,难点在于题目不让额外创建数组,要求就在原数组上进行移动。方法是我们去找非0的数,从第一个数开始遍历数组,只要这个数不是0,我们就让他和第一个数交换,遍历完之后,前面的数肯定就是非0的数了
Python code:
class Solution:
def moveZeroes(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
j = 0
for i in range(len(nums)):
if nums[i] != 0:
nums[j], nums[i] = nums[i], nums[j] # 交换nums[i]和nums[j]
j += 1
problems 5:Best Time to Buy and Sell Stock II
Say you have an array
prices
for which the i t h i^{th} ith element is the price of a given stock on day i.
Design an algorithm to find the maximum profit. You may complete as many transactions as you like (i.e., buy one and sell one share of the stock multiple times).
Note: You may not engage in multiple transactions at the same time (i.e., you must sell the stock before you buy again).
Example 1:Input: [7,1,5,3,6,4] Output: 7 Explanation: Buy on day 2 (price = 1) and sell on day 3 (price = 5), profit = 5-1 = 4. Then buy on day 4 (price = 3) and sell on day 5 (price = 6), profit = 6-3 = 3.
Example 2:
Input: [1,2,3,4,5] Output: 4 Explanation: Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4. Note that you cannot buy on day 1, buy on day 2 and sell them later, as you are engaging multiple transactions at the same time. You must sell before buying again.
Constraints:
1 <= prices.length <= 3 ∗ 1 0 4 3*10^4 3∗104
0 <= prices[i] <= 1 0 4 10 ^ 4 104
Mycode:
class Solution:
def maxProfit(self, prices: List[int]) -> int:
res = 0
for i in range(len(prices)-1):
if prices[i+1] > prices[i]:
res += prices[i+1] - prices[i]
return res
problems 6:Group Anagrams
Given an array of strings
strs
, group the anagrams together. You can return the answer in any order.
An Anagram is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.
Example 1:Input: strs = ["eat","tea","tan","ate","nat","bat"] Output: [["bat"],["nat","tan"],["ate","eat","tea"]]
Example 2:
Input: strs = [""] Output: [[""]]
Example 3:
Input: strs = ["a"] Output: [["a"]]
Constraints:
- 1 <= strs.length <= 1 0 4 10^4 104
- 0 <= strs[i].length <= 100
strs[i]
consists of lower-case English letters.
这道题给出了一个字符串数组(由小写字母组成),让我们把字符串数组中的由相同字符打乱顺序构成的不同字符串:Anagram重新组合起来构成一个新的字符串数组,把这些组合字符串数组再合成一个新的数组,看样例应该能很快明白题意。
方法是:首先明确一点,如果两个字符串是Anagram当且仅当它们排序后相等,然后我们用到一个字典或者映射map(C++),这个映射的key存排好序的字符串,value存放原来的字符串,但是注意,value是一个存放字符串数组,因为后面有排序后相同内容的字符串就直接添加到字符串数组里面了。我们对整个字符串数组进行遍历,遍历的时候首先定义一个变量保存该字符串排序后的内容,如果映射不存在,就直接按上面讲的键值对添加到映射里面,如果存在了,就直接添加到这个字符串数组里,最后返回该映射的值就行了。
Python code:
class Solution:
'''
Input: strs = ["eat","tea","tan","ate","nat","bat"]
Output: [["bat"],["nat","tan"],["ate","eat","tea"]]
'''
def groupAnagrams(self, strs) :
dic = {}
for i in strs:
sorted_s = ''.join(sorted(i))
if sorted_s not in dic:
dic[sorted_s] = [i]
else:
dic[sorted_s].append(i)
return list(dic.values())
solve = Solution()
l = input().split(',')
res = solve.groupAnagrams(l)
print(res)
另外给出以下leetcode官方Python题解:
class Solution(object):
def groupAnagrams(self, strs):
ans = collections.defaultdict(list)
for s in strs:
ans[tuple(sorted(s))].append(s)
return ans.values()
官方题解用到了Python中collections模块里面的defaultdict类,这个类的用法和dict相似,也是一个字典,但是比原生字典好用,他在创建时可以指定一种类型list
,str
,int
等,当我们要查找某个键的值时,若不存在,他就直接返回默认预先定义的空类型,不会报错。
problem 7:Counting Elements
Given an integer array arr, count element x such that x + 1 is also in arr.
If there’re duplicates in arr, count them seperately.
Example 1:Input: Input: arr = [1,2,3] Output: 2 Explanation: 1 and 2 are counted cause 2 and 3 are in arr.
Example 2:
Input: arr = [1,1,3,3,5,5,7,7] Output: 0 Explanation: No numbers are counted, cause there’s no 2, 4, 6, or 8 in arr.
Example 3:
Input: arr = [1,3,2,3,5,0] Output: 3 Explanation: 0, 1 and 2 are counted cause 1, 2 and 3 are in arr.
Example 4:
Input: arr = [1,1,2,2] Output: 2 Explanation: Two 1s are counted cause 2 is in arr.
题意是是让我们计算一个数组中某种元素的数量,如果比该元素大1的数也在该数组,那么计算数量+1.方法是我们创建一个集合,存放数组所有的元素,然后遍历该数组,如果在集合里存在比它大1的数,数量+1.
Mycode:
class Solution:
def countElements(self, arr):
s = set(arr)
cnt = 0
for i in arr:
if i+1 in s:
cnt += 1
return cnt
持续更新······