package main
import (
"container/list"
"fmt"
"math"
"sort"
"strings"
"testing"
)
func TestReadFromFile(t *testing.T) {
fmt.Println("productExceptSelf = ", productExceptSelf([]int{1, 2, 3, 4}))
}
type ListNode struct {
Val int
Next *ListNode
}
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
func min(a, b int) int {
if a > b {
return b
}
return a
}
func max(a, b int) int {
if a < b {
return b
}
return a
}
func swap(nums []int, i, j int) {
nums[i], nums[j] = nums[j], nums[i]
}
func heapify(a []int, i int) {
n := len(a) - 1
for {
minPos := i
if i*2 <= n && a[i*2] < a[minPos] {
minPos = i * 2
}
if i*2+1 <= n && a[i*2+1] < a[minPos] {
minPos = i*2 + 1
}
if minPos == i {
break
}
a[minPos], a[i] = a[i], a[minPos]
i = minPos
}
}
func siftDown(nums []int, index int) {
numsLen := len(nums)
minIndex := index
for {
left, right := 2*index+1, 2*index+2
if left < numsLen && nums[left] < nums[minIndex] {
minIndex = left
}
if right < numsLen && nums[right] < nums[minIndex] {
minIndex = right
}
if minIndex == index {
break
}
swap(nums, index, minIndex)
index = minIndex
}
}
func siftUp(nums []int) {
numsLen := len(nums)
for parent := numsLen/2 - 1; parent >= 0; parent-- {
minIndex := parent
left, right := 2*parent+1, 2*parent+2
if left < numsLen && nums[left] < nums[minIndex] {
minIndex = left
}
if right < numsLen && nums[right] < nums[minIndex] {
minIndex = right
}
if parent != minIndex {
swap(nums, parent, minIndex)
}
}
}
func twoSum(nums []int, target int) []int {
m := map[int]int{}
for i, v := range nums {
if k, ok := m[target-v]; ok {
return []int{k, i}
}
m[v] = i
}
return nil
}
func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
list := &ListNode{0, nil}
result := list
tmp := 0
for l1 != nil || l2 != nil || tmp != 0 {
if l1 != nil {
tmp += l1.Val
l1 = l1.Next
}
if l2 != nil {
tmp += l2.Val
l2 = l2.Next
}
list.Next = &ListNode{tmp % 10, nil}
tmp = tmp / 10
list = list.Next
}
return result.Next
}
func reverseList(head *ListNode) *ListNode {
prev, cur := new(ListNode), head
for cur != nil {
cur.Next, prev, cur = prev, cur, cur.Next
}
return prev
}
func swapPairs(head *ListNode) *ListNode {
dummy := &ListNode{
Val: -1,
Next: head,
}
preNode := dummy
for head != nil && head.Next != nil {
first := head
second := head.Next
preNode.Next, second.Next, first.Next = second, first, second.Next
preNode = first
head = first.Next
}
return dummy.Next
}
func reverseBetween(head *ListNode, m int, n int) *ListNode {
dummy := &ListNode{
Next: head,
}
prem := dummy
for i := 1; i <= m-1; i++ {
prem = prem.Next
}
prev, cur := new(ListNode), head
for i := m; i <= n; i++ {
cur.Next, prev, cur = prev, cur, cur.Next
}
prem.Next.Next = cur
prem.Next = prev
return dummy.Next
}
func hasCycle(head *ListNode) bool {
fast, slow := head, head
for fast != nil && fast.Next != nil {
fast = fast.Next.Next
slow = slow.Next
if fast == slow {
return true
}
}
return false
}
func getIntersectionNode(headA, headB *ListNode) *ListNode {
curA, curB := headA, headB
for curA != curB {
if curA == nil {
curA = headB
} else {
curA = curA.Next
}
if curB == nil {
curB = headA
} else {
curB = curB.Next
}
}
return curA
}
func mergeTwoLists(l1 *ListNode, l2 *ListNode) *ListNode {
prehead := &ListNode{}
result := prehead
for l1 != nil && l2 != nil {
if l1.Val < l2.Val {
prehead.Next = l1
l1 = l1.Next
} else {
prehead.Next = l2
l2 = l2.Next
}
prehead = prehead.Next
}
if l1 != nil {
prehead.Next = l1
}
if l2 != nil {
prehead.Next = l2
}
return result.Next
}
func mergeKLists(lists []*ListNode) *ListNode {
length := len(lists)
switch length {
case 0:
return nil
case 1:
return lists[0]
}
first := mergeKLists(lists[:length/2])
second := mergeKLists(lists[length/2:])
return mergeTwoLists(first, second)
}
func removeNthFromEnd(head *ListNode, n int) *ListNode {
result := &ListNode{}
result.Next = head
pre, cur := new(ListNode), result
i := 1
for head != nil {
if i >= n {
pre = cur
cur = cur.Next
}
head = head.Next
i++
}
pre.Next = pre.Next.Next
return result.Next
}
func isPalindrome(head *ListNode) bool {
if head == nil {
return true
}
var res []*ListNode
for head != nil {
res = append(res, head)
head = head.Next
}
left := 0
right := len(res) - 1
for left < right {
if res[left].Val != res[right].Val {
return false
}
left++
right--
}
return true
}
func reverseWords(s string) string {
strList := strings.Split(s, " ")
var res []string
for i := len(strList) - 1; i >= 0; i-- {
str := strings.TrimSpace(strList[i])
if len(str) > 0 {
res = append(res, strList[i])
}
}
return strings.Join(res, " ")
}
func longestCommonPrefix(strs []string) string {
if len(strs) < 1 {
return ""
}
prefix := strs[0]
for _, k := range strs {
for strings.Index(k, prefix) != 0 {
if len(prefix) == 0 {
return ""
}
prefix = prefix[:len(prefix)-1]
}
}
return prefix
}
func rotate(nums []int, k int) []int {
reverse(nums)
reverse(nums[:k%len(nums)])
reverse(nums[k%len(nums):])
return nums
}
func reverse(arr []int) {
for i := 0; i < len(arr)/2; i++ {
arr[i], arr[len(arr)-i-1] = arr[len(arr)-i-1], arr[i]
}
}
func intersect(nums1 []int, nums2 []int) []int {
i, j, k := 0, 0, 0
sort.Ints(nums1)
sort.Ints(nums2)
for i < len(nums1) && j < len(nums2) {
if nums1[i] > nums2[j] {
j++
} else if nums1[i] < nums2[j] {
i++
} else {
nums1[k] = nums1[i]
i++
j++
k++
}
}
return nums1[:k]
}
func removeElement(nums []int, val int) []int {
for i := 0; i < len(nums); {
if nums[i] == val {
nums = append(nums[:i], nums[i+1:]...)
} else {
i++
}
}
return nums
}
func removeDuplicates(nums []int) int {
for i := 0; i+1 < len(nums); {
if nums[i] == nums[i+1] {
nums = append(nums[:i], nums[i+1:]...)
} else {
i++
}
}
return len(nums)
}
func productExceptSelf(nums []int) []int {
ans := make([]int, len(nums))
k := 1
for i := 0; i < len(nums); i++ {
ans[i] = k
k = k * nums[i]
}
k = 1
fmt.Println("ans = ", ans)
for i := len(nums) - 1; i >= 0; i-- {
ans[i] *= k
k = k * nums[i]
}
return ans
}
func nextPermutation(nums []int) {
if len(nums) <= 1 {
return
}
i, j, k := len(nums)-2, len(nums)-1, len(nums)-1
for i >= 0 && nums[i] >= nums[j] {
i--
j--
}
if i >= 0 {
for nums[i] >= nums[k] {
k--
}
nums[i], nums[k] = nums[k], nums[i]
}
for i, j := j, len(nums)-1; i < j; i, j = i+1, j-1 {
nums[i], nums[j] = nums[j], nums[i]
}
}
func maxProfit(prices []int) int {
sum := 0
for i := 1; i < len(prices); i++ {
if prices[i]-prices[i-1] > 0 {
sum += prices[i] - prices[i-1]
}
}
return sum
}
func maxProfitOnce(prices []int) int {
var min = math.MaxInt32
var maxDiff int
for i := 0; i < len(prices); i++ {
if min > prices[i] {
min = prices[i]
}
diff := prices[i] - min
if maxDiff < diff {
maxDiff = diff
}
}
return maxDiff
}
func maxSubArray(nums []int) int {
max := math.MinInt32
tmp := 0
for _, v := range nums {
if tmp > 0 {
tmp += v
} else {
tmp = v
}
if max < tmp {
max = tmp
}
}
return max
}
func maxSubArrayDP(nums []int) int {
if len(nums) < 1 {
return 0
}
dp := make([]int, len(nums))
result := nums[0]
dp[0] = nums[0]
for i := 1; i < len(nums); i++ {
dp[i] = max(dp[i-1]+nums[i], nums[i])
result = max(dp[i], result)
}
return result
}
func maxProduct(nums []int) int {
maxDP := make([]int, len(nums))
minDP := make([]int, len(nums))
maxDP[0] = nums[0]
minDP[0] = nums[0]
max := nums[0]
for i := 1; i < len(nums); i++ {
maxDP[i], minDP[i] = numCompare(minDP[i-1]*nums[i], maxDP[i-1]*nums[i], nums[i])
if max < maxDP[i] {
max = maxDP[i]
}
}
return max
}
func numCompare(a, b, c int) (max, min int) {
s := []int{a, b, c}
sort.Ints(s)
return s[2], s[0]
}
func lengthOfLIS(nums []int) int {
if len(nums) < 1 {
return 0
}
dp := make([]int, len(nums))
result := 1
for i := 0; i < len(nums); i++ {
dp[i] = 1
for j := 0; j < i; j++ {
if nums[j] < nums[i] {
dp[i] = max(dp[j]+1, dp[i])
}
}
result = max(result, dp[i])
}
return result
}
func findPeakElement(nums []int) int {
left, right := 0, len(nums)-1
for left < right {
mid := left + (right-left)/2
if nums[mid] > nums[mid+1] {
right = mid
} else {
left = mid + 1
}
}
return left
}
func findMin(nums []int) int {
left, right := 0, len(nums)-1
for left < right {
mid := left + (right-left)/2
if nums[mid] > nums[right] {
left = mid + 1
} else {
right = mid
}
}
return nums[left]
}
func firstNumIndex(array []int, n int) int {
low, high := 0, len(array)
for low <= high {
mid := low + (high-low)/2
if array[mid] < n {
low = mid + 1
} else if array[mid] > n {
high = mid - 1
} else {
if mid == 0 || array[mid-1] != n {
return mid
} else {
high = mid - 1
}
}
}
return -1
}
func firstBigNumIndex(array []int, n int) int {
low, high := 0, len(array)
for low <= high {
mid := low + (high-low)/2
if array[mid] >= n {
if mid == 0 || array[mid-1] < n {
return mid
} else {
high = mid - 1
}
} else {
low = mid + 1
}
}
return -1
}
func MaxSubStringLength(s string) int {
n, ans := len(s), 0
m := make(map[byte]int, 0)
for end, start := 0, 0; end < n; end++ {
if v, ok := m[s[end]]; ok {
start = int(math.Max(float64(v), float64(start)))
}
ans = int(math.Max(float64(ans), float64(end-start)))
m[s[end]] = end
}
return ans
}
func sortArrayByParity(A []int) []int {
j := 0
for i := range A {
if A[i]%2 == 0 {
A[j], A[i] = A[i], A[j]
j++
}
}
return A
}
func quickSort(arr []int) {
start, end := 0, len(arr)-1
quickCore(arr, start, end)
}
func quickCore(arr []int, start int, end int) {
i, j := start, end
key := arr[start]
for i <= j {
for arr[i] < key {
i++
}
for arr[j] > key {
j--
}
if i <= j {
arr[i], arr[j] = arr[j], arr[i]
i++
j--
}
}
if start < j {
quickCore(arr, start, j)
}
if end > i {
quickCore(arr, i, end)
}
}
func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
if root == nil || root == p || root == q {
return root
}
l := lowestCommonAncestor(root.Left, p, q)
r := lowestCommonAncestor(root.Right, p, q)
if l == nil {
return r
}
if r == nil {
return l
}
return root
}
func buildTree(preorder []int, inorder []int) *TreeNode {
for k := range inorder {
if inorder[k] == preorder[0] {
return &TreeNode{
Val: preorder[0],
Left: buildTree(preorder[1:k+1], inorder[0:k]),
Right: buildTree(preorder[k+1:], inorder[k+1:]),
}
}
}
return nil
}
func isValidBST(root *TreeNode) bool {
if root == nil {
return true
}
return isBST(root, math.MinInt64, math.MaxInt64)
}
func isBST(root *TreeNode, min, max int) bool {
if root == nil {
return true
}
if min >= root.Val || max <= root.Val {
return false
}
return isBST(root.Left, min, root.Val) && isBST(root.Right, root.Val, max)
}
func levelOrder(root *TreeNode) [][]int {
var result [][]int
if root == nil {
return result
}
queue := list.New()
queue.PushFront(root)
for queue.Len() > 0 {
var current []int
listLength := queue.Len()
for i := 0; i < listLength; i++ {
node := queue.Remove(queue.Back()).(*TreeNode)
current = append(current, node.Val)
if node.Left != nil {
queue.PushFront(node.Left)
}
if node.Right != nil {
queue.PushFront(node.Right)
}
}
result = append(result, current)
}
return result
}
func isSymmetric(root *TreeNode) bool {
if root == nil {
return true
}
return dfsIsSymmetric(root.Left, root.Right)
}
func dfsIsSymmetric(a, b *TreeNode) bool {
if a == nil && b == nil {
return true
}
if (a == nil && b != nil) || (a != nil && b == nil) || (a.Val != b.Val) {
return false
}
return dfsIsSymmetric(a.Left, b.Right) && dfsIsSymmetric(a.Right, b.Left)
}
type MyQueue struct {
input []int
output []int
}
func Constructor() MyQueue {
return MyQueue{}
}
func (this *MyQueue) Push(x int) {
this.input = append(this.input, x)
}
func (this *MyQueue) Pop() int {
this.Peek()
e := this.output[len(this.output)-1]
this.output = this.output[:len(this.output)-1]
return e
}
func (this *MyQueue) Peek() int {
if len(this.output) == 0 {
for len(this.input) > 0 {
this.output = append(this.output, this.input[len(this.input)-1])
this.input = this.input[:len(this.input)-1]
}
}
return this.output[len(this.output)-1]
}
func (this *MyQueue) Empty() bool {
if len(this.input) == 0 && len(this.output) == 0 {
return true
}
return false
}