给定一个字符串 s ,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。
输入:s = "Let's take LeetCode contest" 输出:"s'teL ekat edoCteeL tsetnoc"
func reverseWords(s string) string {
length := len(s)
ret := []byte{}
for i := 0; i < length; {
start := i
for i < length && s[i] != ' ' {
i++
}
for p := start; p < i; p++ {
ret = append(ret, s[start + i - 1 - p])
}
for i < length && s[i] == ' ' {
i++
ret = append(ret, ' ')
}
}
return string(ret)
}
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
输入:s = ["h","e","l","l","o"] 输出:["o","l","l","e","h"]
func reverseString(s []byte) {
for left, right := 0, len(s)-1; left < right; left++ {
s[left], s[right] = s[right], s[left]
right--
}
}
你和你的朋友,两个人一起玩 Nim 游戏:
桌子上有一堆石头。
你们轮流进行自己的回合, 你作为先手 。
每一回合,轮到的人拿掉 1 - 3 块石头。
拿掉最后一块石头的人就是获胜者。
假设你们每一步都是最优解。请编写一个函数,来判断你是否可以在给定石头数量为 n 的情况下赢得游戏。如果可以赢,返回 true;否则,返回 false
func canWinNim(n int) bool {
return n%4 != 0
}
除自身以外数组的乘积
给你一个整数数组 nums,返回数组answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。
题目数据保证数组nums之中任意元素的全部前缀元素和后缀的乘积都在32位整数范围内。请不要使用除法,且在 O(n) 时间复杂度内完成此题。
func productExceptSelf(nums []int) []int {
length := len(nums)
answer := make([]int, length)
// answer[i] 表示索引 i 左侧所有元素的乘积
// 因为索引为 '0' 的元素左侧没有元素, 所以 answer[0] = 1
answer[0] = 1
for i := 1; i < length; i++ {
answer[i] = nums[i-1] * answer[i-1]
}
// R 为右侧所有元素的乘积
// 刚开始右边没有元素,所以 R = 1
R := 1
for i := length - 1; i >= 0; i-- {
// 对于索引 i,左边的乘积为 answer[i],右边的乘积为 R
answer[i] = answer[i] * R
// R 需要包含右边所有的乘积,所以计算下一个结果时需要将当前值乘到 R 上
R *= nums[i]
}
return answer
}
请编写一个函数,用于 删除单链表中某个特定节点 。在设计函数时需要注意,你无法访问链表的头节点 head ,只能直接访问 要被删除的节点 。
题目数据保证需要删除的节点 不是末尾节点
func deleteNode(node *ListNode) {
node.Val = node.Next.Val
node.Next = node.Next.Next
}
给定一个二叉搜索树的根节点 root ,和一个整数 k ,请你设计一个算法查找其中第 k 个最小元素(从 1 开始计数)
中序遍历
func kthSmallest(root *TreeNode, k int) int {
stack := []*TreeNode{}
for {
for root != nil {
stack = append(stack, root)
root = root.Left
}
stack, root = stack[:len(stack)-1], stack[len(stack)-1]
k--
if k == 0 {
return root.Val
}
root = root.Right
}
}
记录子树的结点数
type MyBst struct {
root *TreeNode
nodeNum map[*TreeNode]int // 统计以每个结点为根结点的子树的结点数,并存储在哈希表中
}
// 统计以 node 为根结点的子树的结点数
func (t *MyBst) countNodeNum(node *TreeNode) int {
if node == nil {
return 0
}
t.nodeNum[node] = 1 + t.countNodeNum(node.Left) + t.countNodeNum(node.Right)
return t.nodeNum[node]
}
// 返回二叉搜索树中第 k 小的元素
func (t *MyBst) kthSmallest(k int) int {
node := t.root
for {
leftNodeNum := t.nodeNum[node.Left]
if leftNodeNum < k-1 {
node = node.Right
k -= leftNodeNum + 1
} else if leftNodeNum == k-1 {
return node.Val
} else {
node = node.Left
}
}
}
func kthSmallest(root *TreeNode, k int) int {
t := &MyBst{root, map[*TreeNode]int{}}
t.countNodeNum(root)
return t.kthSmallest(k)
}
给你一个整数数组
nums
。如果任一值在数组中出现 至少两次 ,返回true
;如果数组中每个元素互不相同,返回false
。
func containsDuplicate(nums []int) bool {
set := map[int]struct{}{}
for _, v := range nums {
if _, has := set[v]; has {
return true
}
set[v] = struct{}{}
}
return false
}
fmt.Println(struct{}{})打印为{},d, hass := set[v] fmt.Println(hass) fmt.Println(d)打印为{}和true或者false
给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。 请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
基于堆排序的选择方法
func findKthLargest(nums []int, k int) int {
heapSize := len(nums)
buildMaxHeap(nums, heapSize)
for i := len(nums) - 1; i >= len(nums) - k + 1; i-- {
nums[0], nums[i] = nums[i], nums[0]
heapSize--
maxHeapify(nums, 0, heapSize)
}
return nums[0]
}
func buildMaxHeap(a []int, heapSize int) {
for i := heapSize/2; i >= 0; i-- {
maxHeapify(a, i, heapSize)
}
}
func maxHeapify(a []int, i, heapSize int) {
l, r, largest := i * 2 + 1, i * 2 + 2, i
if l < heapSize && a[l] > a[largest] {
largest = l
}
if r < heapSize && a[r] > a[largest] {
largest = r
}
if largest != i {
a[i], a[largest] = a[largest], a[i]
maxHeapify(a, largest, heapSize)
}
}