添加 problem 441、457、781、984

This commit is contained in:
YDZ
2019-07-23 18:03:13 +08:00
parent 412552bdeb
commit 73b73f0e68
10 changed files with 465 additions and 0 deletions

View File

@ -0,0 +1,22 @@
package leetcode
import "math"
// 解法一 数学公式
func arrangeCoins(n int) int {
if n <= 0 {
return 0
}
x := math.Sqrt(2*float64(n)+0.25) - 0.5
return int(x)
}
// 解法二 模拟
func arrangeCoins1(n int) int {
k := 1
for n >= k {
n -= k
k++
}
return k - 1
}

View File

@ -0,0 +1,47 @@
package leetcode
import (
"fmt"
"testing"
)
type question441 struct {
para441
ans441
}
// para 是参数
// one 代表第一个参数
type para441 struct {
n int
}
// ans 是答案
// one 代表第一个答案
type ans441 struct {
one int
}
func Test_Problem441(t *testing.T) {
qs := []question441{
question441{
para441{5},
ans441{2},
},
question441{
para441{8},
ans441{3},
},
}
fmt.Printf("------------------------Leetcode Problem 441------------------------\n")
for _, q := range qs {
_, p := q.ans441, q.para441
fmt.Printf("【input】:%v 【output】:%v\n", p, arrangeCoins(p.n))
}
fmt.Printf("\n\n\n")
}

View File

@ -0,0 +1,45 @@
# [441. Arranging Coins](https://leetcode.com/problems/arranging-coins/)
## 题目:
You have a total of n coins that you want to form in a staircase shape, where every k-th row must have exactly k coins.
Given n, find the total number of **full** staircase rows that can be formed.
n is a non-negative integer and fits within the range of a 32-bit signed integer.
**Example 1:**
n = 5
The coins can form the following rows:
¤
¤ ¤
¤ ¤
Because the 3rd row is incomplete, we return 2.
**Example 2:**
n = 8
The coins can form the following rows:
¤
¤ ¤
¤ ¤ ¤
¤ ¤
Because the 4th row is incomplete, we return 3.
## 题目大意
你总共有 n 枚硬币你需要将它们摆成一个阶梯形状 k 行就必须正好有 k 枚硬币。给定一个数字 n找出可形成完整阶梯行的总行数。n 是一个非负整数并且在32位有符号整型的范围内。
## 解题思路
- n 个硬币,按照递增的方式排列搭楼梯,第一层一个,第二层二个,……第 n 层需要 n 个硬币。问硬币 n 能够搭建到第几层?
- 这一题有 2 种解法,第一种解法就是解方程求出 X`(1+x)x/2 = n`,即 `x = floor(sqrt(2*n+1/4) - 1/2)`,第二种解法是模拟。

View File

@ -0,0 +1,37 @@
package leetcode
func circularArrayLoop(nums []int) bool {
if len(nums) == 0 {
return false
}
for i := 0; i < len(nums); i++ {
if nums[i] == 0 {
continue
}
// slow/fast pointer
slow, fast, val := i, getNextIndex(nums, i), 0
for nums[fast]*nums[i] > 0 && nums[getNextIndex(nums, fast)]*nums[i] > 0 {
if slow == fast {
// check for loop with only one element
if slow == getNextIndex(nums, slow) {
break
}
return true
}
slow = getNextIndex(nums, slow)
fast = getNextIndex(nums, getNextIndex(nums, fast))
}
// loop not found, set all element along the way to 0
slow, val = i, nums[i]
for nums[slow]*val > 0 {
next := getNextIndex(nums, slow)
nums[slow] = 0
slow = next
}
}
return false
}
func getNextIndex(nums []int, index int) int {
return ((nums[index]+index)%len(nums) + len(nums)) % len(nums)
}

View File

@ -0,0 +1,76 @@
package leetcode
import (
"fmt"
"testing"
)
type question457 struct {
para457
ans457
}
// para 是参数
// one 代表第一个参数
type para457 struct {
one []int
}
// ans 是答案
// one 代表第一个答案
type ans457 struct {
one bool
}
func Test_Problem457(t *testing.T) {
qs := []question457{
question457{
para457{[]int{-1}},
ans457{false},
},
question457{
para457{[]int{3, 1, 2}},
ans457{true},
},
question457{
para457{[]int{-8, -1, 1, 7, 2}},
ans457{false},
},
question457{
para457{[]int{-1, -2, -3, -4, -5}},
ans457{false},
},
question457{
para457{[]int{}},
ans457{false},
},
question457{
para457{[]int{2, -1, 1, 2, 2}},
ans457{true},
},
question457{
para457{[]int{-1, 2}},
ans457{false},
},
question457{
para457{[]int{-2, 1, -1, -2, -2}},
ans457{false},
},
}
fmt.Printf("------------------------Leetcode Problem 457------------------------\n")
for _, q := range qs {
_, p := q.ans457, q.para457
fmt.Printf("【input】:%v 【output】:%v\n", p, circularArrayLoop(p.one))
}
fmt.Printf("\n\n\n")
}

View File

@ -0,0 +1,59 @@
# [457. Circular Array Loop](https://leetcode.com/problems/circular-array-loop/)
## 题目:
You are given a **circular** array `nums` of positive and negative integers. If a number k at an index is positive, then move forward k steps. Conversely, if it's negative (-k), move backward k steps. Since the array is circular, you may assume that the last element's next element is the first element, and the first element's previous element is the last element.
Determine if there is a loop (or a cycle) in `nums`. A cycle must start and end at the same index and the cycle's length > 1. Furthermore, movements in a cycle must all follow a single direction. In other words, a cycle must not consist of both forward and backward movements.
**Example 1:**
Input: [2,-1,1,2,2]
Output: true
Explanation: There is a cycle, from index 0 -> 2 -> 3 -> 0. The cycle's length is 3.
**Example 2:**
Input: [-1,2]
Output: false
Explanation: The movement from index 1 -> 1 -> 1 ... is not a cycle, because the cycle's length is 1. By definition the cycle's length must be greater than 1.
**Example 3:**
Input: [-2,1,-1,-2,-2]
Output: false
Explanation: The movement from index 1 -> 2 -> 1 -> ... is not a cycle, because movement from index 1 -> 2 is a forward movement, but movement from index 2 -> 1 is a backward movement. All movements in a cycle must follow a single direction.
**Note:**
1. -1000 ≤ nums[i] ≤ 1000
2. nums[i] ≠ 0
3. 1 ≤ nums.length ≤ 5000
**Follow up:**
Could you solve it in **O(n)** time complexity and **O(1)** extra space complexity?
## 题目大意
给定一个含有正整数和负整数的环形数组 nums。 如果某个索引中的数 k 为正数则向前移动 k 个索引。相反如果是负数 (-k),则向后移动 k 个索引。因为数组是环形的所以可以假设最后一个元素的下一个元素是第一个元素而第一个元素的前一个元素是最后一个元素。
确定 nums 中是否存在循环或周期。循环必须在相同的索引处开始和结束并且循环长度 > 1。此外一个循环中的所有运动都必须沿着同一方向进行。换句话说一个循环中不能同时包括向前的运动和向后的运动。
提示:
- -1000 ≤ nums[i] ≤ 1000
- nums[i] ≠ 0
- 1 ≤ nums.length ≤ 5000
进阶:
- 你能写出时间时间复杂度为 O(n) 和额外空间复杂度为 O(1) 的算法吗?
## 解题思路
- 给出一个循环数组,数组的数字代表了前进和后退的步数,+ 代表往右(前进)- 代表往左(后退)。问这个循环数组中是否存在一个循环,并且这个循环内不能只有一个元素,循环的方向都必须是同方向的。
- 遇到循环就可以优先考虑用快慢指针的方法判断循环,这一题对循环增加了一个条件,循环不能只是单元素的循环,所以在快慢指针中加入这个判断条件。还有一个判断条件是循环的方向必须是同向的,这个简单,用 `num[i] * num[j] > 0` 就可以判断出是同向的(如果是反向的,那么两者的乘积必然是负数),如果没有找到循环,可以将当前已经走过的路径上的 num[] 值都置为 0标记已经访问过了。下次循环遇到访问过的元素`num[i] * num[j] > 0` 就会是 0提前退出找循环的过程。

View File

@ -0,0 +1,46 @@
# [781. Rabbits in Forest](https://leetcode.com/problems/rabbits-in-forest/)
## 题目:
In a forest, each rabbit has some color. Some subset of rabbits (possibly all of them) tell you how many other rabbits have the same color as them. Those `answers` are placed in an array.
Return the minimum number of rabbits that could be in the forest.
Examples:
Input: answers = [1, 1, 2]
Output: 5
Explanation:
The two rabbits that answered "1" could both be the same color, say red.
The rabbit than answered "2" can't be red or the answers would be inconsistent.
Say the rabbit that answered "2" was blue.
Then there should be 2 other blue rabbits in the forest that didn't answer into the array.
The smallest possible number of rabbits in the forest is therefore 5: 3 that answered plus 2 that didn't.
Input: answers = [10, 10, 10]
Output: 11
Input: answers = []
Output: 0
**Note:**
1. `answers` will have length at most `1000`.
2. Each `answers[i]` will be an integer in the range `[0, 999]`.
## 题目大意
森林中,每个兔子都有颜色。其中一些兔子(可能是全部)告诉你还有多少其他的兔子和自己有相同的颜色。我们将这些回答放在 answers 数组里。返回森林中兔子的最少数量。
说明:
- answers 的长度最大为1000。
- answers[i] 是在 [0, 999] 范围内的整数。
## 解题思路
- 给出一个数组,数组里面代表的是每个兔子说自己同类还有多少个。要求输出总共有多少只兔子。数字中可能兔子汇报的人数小于总兔子数。
- 这一题关键在于如何划分不同种类的兔子,有可能相同种类的兔子的个数是一样的,比如 `[2,2,2,2,2,2]`,这其实是 3 个种类,总共 6 只兔子。用 map 去重相同种类的兔子,不断的减少,当有种类的兔子为 0 以后,还有该种类的兔子报数,需要当做另外一个种类的兔子来看待。

View File

@ -0,0 +1,36 @@
package leetcode
func strWithout3a3b(A int, B int) string {
ans, a, b := "", "a", "b"
if B < A {
A, B = B, A
a, b = b, a
}
Dif := B - A
if A == 1 && B == 1 { // ba
ans = b + a
} else if A == 1 && B < 5 { // bbabb
for i := 0; i < B-2; i++ {
ans = ans + b
}
ans = b + b + a + ans
} else if (B-A)/A >= 1 { //bbabbabb
for i := 0; i < A; i++ {
ans = ans + b + b + a
B = B - 2
}
for i := 0; i < B; i++ {
ans = ans + b
}
} else { //bbabbabbabbabababa
for i := 0; i < Dif; i++ {
ans = ans + b + b + a
B -= 2
A--
}
for i := 0; i < B; i++ {
ans = ans + b + a
}
}
return ans
}

View File

@ -0,0 +1,48 @@
package leetcode
import (
"fmt"
"testing"
)
type question984 struct {
para984
ans984
}
// para 是参数
// one 代表第一个参数
type para984 struct {
a int
b int
}
// ans 是答案
// one 代表第一个答案
type ans984 struct {
one string
}
func Test_Problem984(t *testing.T) {
qs := []question984{
question984{
para984{1, 2},
ans984{"abb"},
},
question984{
para984{4, 1},
ans984{"aabaa"},
},
}
fmt.Printf("------------------------Leetcode Problem 984------------------------\n")
for _, q := range qs {
_, p := q.ans984, q.para984
fmt.Printf("【input】:%v 【output】:%v\n", p, strWithout3a3b(p.a, p.b))
}
fmt.Printf("\n\n\n")
}

View File

@ -0,0 +1,49 @@
# [984. String Without AAA or BBB](https://leetcode.com/problems/string-without-aaa-or-bbb/)
## 题目:
Given two integers `A` and `B`, return **any** string `S` such that:
- `S` has length `A + B` and contains exactly `A` `'a'` letters, and exactly `B` `'b'`letters;
- The substring `'aaa'` does not occur in `S`;
- The substring `'bbb'` does not occur in `S`.
**Example 1:**
Input: A = 1, B = 2
Output: "abb"
Explanation: "abb", "bab" and "bba" are all correct answers.
**Example 2:**
Input: A = 4, B = 1
Output: "aabaa"
**Note:**
1. `0 <= A <= 100`
2. `0 <= B <= 100`
3. It is guaranteed such an `S` exists for the given `A` and `B`.
## 题目大意
给定两个整数 A  B返回任意字符串 S要求满足
- S 的长度为 A + B且正好包含 A 个 'a' 字母与 B 个 'b' 字母;
- 子串 'aaa' 没有出现在 S 
- 子串 'bbb' 没有出现在 S 中。
提示:
- 0 <= A <= 100
- 0 <= B <= 100
- 对于给定的 A 和 B保证存在满足要求的 S。
## 解题思路
- 给出 A 和 B 的个数,要求组合出字符串,不能出现 3 个连续的 A 和 3 个连续的 B。这题由于只可能有 4 种情况,暴力枚举就可以了。假设 B 的个数比 A 多(如果 A 多,就交换一下 A 和 B),最终可能的情况只可能是这 4 种情况中的一种: `ba``bbabb``bbabbabb``bbabbabbabbabababa`