Skip to content

Commit 870d289

Browse files
authored
Merge pull request algorithm007-class02#176 from zhangqianvvw/master
0334_Week01(go)
2 parents d567323 + 1629505 commit 870d289

17 files changed

Lines changed: 697 additions & 1 deletion

File tree

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package main
2+
3+
import "fmt"
4+
5+
// https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array/
6+
// 26. 删除排序数组中的重复项
7+
//给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。
8+
//
9+
// 不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
10+
//
11+
//
12+
//
13+
// 示例 1:
14+
//
15+
// 给定数组 nums = [1,1,2],
16+
//
17+
//函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。
18+
//
19+
//你不需要考虑数组中超出新长度后面的元素。
20+
//
21+
// 示例 2:
22+
//
23+
// 给定 nums = [0,0,1,1,1,2,2,3,3,4],
24+
//
25+
//函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4。
26+
//
27+
//你不需要考虑数组中超出新长度后面的元素。
28+
//
29+
//
30+
//
31+
//
32+
// 说明:
33+
//
34+
// 为什么返回数值是整数,但输出的答案是数组呢?
35+
//
36+
// 请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。
37+
//
38+
// 你可以想象内部操作如下:
39+
//
40+
// // nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝
41+
//int len = removeDuplicates(nums);
42+
//
43+
//// 在函数里修改输入数组对于调用者是可见的。
44+
//// 根据你的函数返回的长度, 它会打印出数组中该长度范围内的所有元素。
45+
//for (int i = 0; i < len; i++) {
46+
//    print(nums[i]);
47+
//}
48+
//
49+
// Related Topics 数组 双指针
50+
51+
52+
func main() {
53+
nums := []int{1,3,34,34,45,45,45}
54+
removeDuplicates(nums)
55+
removeDuplicates2(nums)
56+
}
57+
58+
/**
59+
left right指针作比较,将相等的移到右侧 d
60+
*/
61+
func removeDuplicates(nums []int) int {
62+
left, right := 0, 1
63+
for ; right < len(nums); right++ {
64+
if nums[left] == nums[right] {
65+
continue
66+
}
67+
left ++
68+
nums[left] = nums[right]
69+
}
70+
return left+1
71+
}
72+
73+
/**
74+
数组覆盖值
75+
*/
76+
func removeDuplicates2(nums []int) int {
77+
for i:=len(nums)-1; i>0; i-- {
78+
if nums[i] == nums[i-1] {
79+
nums = append(nums[:i], nums[i+1:]...)
80+
fmt.Println(nums)
81+
}
82+
}
83+
return len(nums)
84+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package main
2+
3+
import "fmt"
4+
5+
//给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
6+
//
7+
// 示例 1:
8+
//
9+
// 输入: [1,2,3,4,5,6,7] 和 k = 3
10+
//输出: [5,6,7,1,2,3,4]
11+
//解释:
12+
//向右旋转 1 步: [7,1,2,3,4,5,6]
13+
//向右旋转 2 步: [6,7,1,2,3,4,5]
14+
//向右旋转 3 步: [5,6,7,1,2,3,4]
15+
//
16+
//
17+
// 示例 2:
18+
//
19+
// 输入: [-1,-100,3,99] 和 k = 2
20+
//输出: [3,99,-1,-100]
21+
//解释:
22+
//向右旋转 1 步: [99,-1,-100,3]
23+
//向右旋转 2 步: [3,99,-1,-100]
24+
//
25+
// 说明:
26+
//
27+
//
28+
// 尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。
29+
// 要求使用空间复杂度为 O(1) 的 原地 算法。
30+
//
31+
// Related Topics 数组
32+
33+
34+
//leetcode submit region begin(Prohibit modification and deletion)
35+
/**
36+
语法特性,
37+
*/
38+
func rotate(nums []int, k int) {
39+
k %= len(nums)
40+
nums = append(nums[len(nums)-k:], nums[:len(nums)-k]...)
41+
fmt.Println(nums)
42+
}
43+
44+
/**
45+
三层反转,前部分、后部分、全部
46+
*/
47+
func rotate2(nums []int, k int) {
48+
k %= len(nums)
49+
reverse(nums[:len(nums)-k])
50+
reverse(nums[len(nums)-k:])
51+
reverse(nums)
52+
fmt.Println(nums)
53+
}
54+
55+
func reverse(nums []int) {
56+
i,j := 0,len(nums)-1
57+
for i < j{
58+
nums[i], nums[j] = nums[j], nums[i]
59+
i++
60+
j--
61+
}
62+
}
63+
//leetcode submit region end(Prohibit modification and deletion)
64+
65+
func main() {
66+
nums := []int{1,2,3,4,5,6,7}
67+
rotate(nums, 5)
68+
nums = []int{1,2,3,4,5,6,7}
69+
rotate2(nums, 5)
70+
}

Week_02/G20200343040334/NOTE.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,12 @@
1-
学习笔记
1+
### 学习笔记
2+
####
3+
`栈是一种特殊的线性表,具有和线性表的特点,同时也有特殊性:元素遵循“先进后出”的特点,也就是只能从栈顶插入或删除元素。同样可以用顺序存储和链式存储两种方式实现,分别称为顺序栈和链栈。栈结构可以用来实现表达式求值、括号匹配等。
4+
栈的特点可以看成是一个桶,往桶里面装东西,取东西都是从上面进行的,最先放进去的要最后才能取出来`
5+
6+
#### 队列
7+
`队列也是一种特殊的线性表,它的特殊性在于“先进先出”,如同现实生活中的排队问题:先来的人先服务完先走。不同于栈的地方在于队列一端用来插入新元素,一端用来删除元素,即有队首和队尾`
8+
9+
10+
11+
#### hash
12+
`hash碰撞解决方式,拉链法 与开放定址法相比,拉链法有如下几个优点: ①拉链法处理冲突简单,且无堆积现象,即非同义词决不会发生冲突,因此平均查找长度较短; ②由于拉链法中各链表上的结点空间是动态申请的,故它更适合于造表前无法确定表长的情况; ③开放定址法为减少冲突,要求装填因子α较小,故当结点规模较大时会浪费很多空间。而拉链法中可取α≥1,且结点较大时,拉链法中增加的指针域可忽略不计,因此节省空间; ④在用拉链法构造的散列表中,删除结点的操作易于实现。只要简单地删去链表上相应的结点即可。而对开放地址法构造的散列表,删除结点不能简单地将被删结 点的空间置为空,否则将截断在它之后填人散列表的同义词结点的查找路径。这是因为各种开放地址法中,空地址单元(即开放地址)都是查找失败的条件。因此在 用开放地址法处理冲突的散列表上执行删除操作,只能在被删结点上做删除标记,而不能真正删除结点。 (3)拉链法的缺点  拉链法的缺点是:指针需要额外的空间,故当结点规模较小时,开放定址法较为节省空间,而若将节省的指针空间用来扩大散列表的规模,可使装填因子变小,这又减少了开放定址法中的冲突,从而提高平均查找速度。`
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package main
2+
3+
import "fmt"
4+
5+
/**
6+
//给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
7+
//
8+
// 你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
9+
//
10+
// 示例:
11+
//
12+
// 给定 nums = [2, 7, 11, 15], target = 9
13+
//
14+
//因为 nums[0] + nums[1] = 2 + 7 = 9
15+
//所以返回 [0, 1]
16+
//
17+
// Related Topics 数组 哈希表
18+
19+
20+
*/
21+
func main() {
22+
fmt.Println(twoSum([]int{2, 7, 11, 15}, 9))
23+
}
24+
25+
func twoSum(nums []int, target int) []int {
26+
var result []int
27+
maps := map[int]int{}
28+
for index, num := range nums {
29+
if _, ok := maps[target - num]; ok{
30+
result = append(result, index, maps[target - num])
31+
return result
32+
}
33+
maps[num] = index
34+
}
35+
return result
36+
}
37+
38+
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
2+
//
3+
// 你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
4+
//
5+
// 示例:
6+
//
7+
// 给定 nums = [2, 7, 11, 15], target = 9
8+
//
9+
//因为 nums[0] + nums[1] = 2 + 7 = 9
10+
//所以返回 [0, 1]
11+
//
12+
// Related Topics 数组 哈希表
13+
14+
15+
//leetcode submit region begin(Prohibit modification and deletion)
16+
func twoSum(nums []int, target int) []int {
17+
18+
}
19+
//leetcode submit region end(Prohibit modification and deletion)
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
15. 三数之和
2+
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。
3+
4+
注意:答案中不可以包含重复的三元组。
5+
6+
7+
8+
示例:
9+
10+
给定数组 nums = [-1, 0, 1, 2, -1, -4]
11+
12+
满足要求的三元组集合为:
13+
[
14+
[-1, 0, 1],
15+
[-1, -1, 2]
16+
]
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package main
2+
3+
import "fmt"
4+
5+
func main() {
6+
fmt.Println(threeSum([]int{-1, 0, 1, 2, -1, -4}))
7+
}
8+
9+
func threeSum(nums []int) [][]int {
10+
if len(nums) < 3 { return [][]int{} }
11+
12+
QuickSort(nums) // 快排 O(n log n), 本地修改
13+
14+
ret := make([][]int, 0, 0)
15+
for i := 0; i < len(nums) - 1; i++ {
16+
l, r := i + 1, len(nums) - 1
17+
18+
if nums[i] > 0 || nums[i] + nums[l] > 0 { break } // 优化掉不可能的情况
19+
20+
if i > 0 && nums[i] == nums[i-1] { continue } // i 去重
21+
22+
for l < r {
23+
if l > i + 1 && nums[l] == nums[l-1] { // l 去重
24+
l++; continue
25+
}
26+
if r < len(nums) - 2 && nums[r] == nums[r+1] { // r 去重
27+
r--; continue
28+
}
29+
30+
if nums[i] + nums[l] + nums[r] > 0 { //
31+
r--
32+
} else if nums[i] + nums[l] + nums[r] < 0 {
33+
l++
34+
} else {
35+
ret = append(ret, []int{nums[i], nums[l], nums[r]})
36+
l++; r--
37+
}
38+
}
39+
}
40+
41+
return ret
42+
}
43+
44+
func QuickSort(array []int) {
45+
if len(array) < 2 { return }
46+
47+
pivot := array[0]
48+
l, r := 0, len(array) - 1
49+
50+
for i := 1; i <= r; {
51+
if array[i] < pivot { //
52+
array[l], array[i] = array[i], array[l]
53+
l++; i++
54+
} else {
55+
array[r], array[i] = array[i], array[r]
56+
r--
57+
}
58+
}
59+
60+
QuickSort(array[:l])
61+
QuickSort(array[l + 1:])
62+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
20. 有效的括号
2+
3+
给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。
4+
5+
有效字符串需满足:
6+
7+
左括号必须用相同类型的右括号闭合。
8+
左括号必须以正确的顺序闭合。
9+
注意空字符串可被认为是有效字符串。
10+
11+
示例 1:
12+
13+
输入: "()"
14+
输出: true
15+
示例 2:
16+
17+
输入: "()[]{}"
18+
输出: true
19+
示例 3:
20+
21+
输入: "(]"
22+
输出: false
23+
示例 4:
24+
25+
输入: "([)]"
26+
输出: false
27+
示例 5:
28+
29+
输入: "{[]}"
30+
输出: true
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package main
2+
3+
import "fmt"
4+
5+
func main() {
6+
//s:= "({((())))"
7+
s:= "(((())))"
8+
isValid := isValid(s)
9+
fmt.Println(isValid)
10+
}
11+
// 解题思路:
12+
// 定义map dict := map[byte]byte{'(':')','{':'}','[':']'}
13+
// 定义stack数组
14+
// 循环遍历
15+
// if stack为空则判断最后的元素和当前字符在map中是否存在 如果存在则出栈,不存在则继续入栈
16+
func isValid(s string) bool {
17+
dict := map[byte]byte{'(':')','{':'}','[':']'}
18+
var stack []byte
19+
for _,v := range s{
20+
if len(stack) > 0{
21+
if byte(v) == dict[stack[len(stack)-1]]{
22+
stack = stack[:len(stack)-1]
23+
continue
24+
}
25+
}
26+
stack = append(stack, byte(v))
27+
fmt.Println(stack)
28+
}
29+
return len(stack)<1
30+
}

0 commit comments

Comments
 (0)