# 2022-06-08

## [213. House Robber II](https://leetcode.com/problems/house-robber-ii/)

### Description

You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed. All houses at this place are **arranged in a circle.** That means the first house is the neighbor of the last one. Meanwhile, adjacent houses have a security system connected, and **it will automatically contact the police if two adjacent houses were broken into on the same night**.

Given an integer array `nums` representing the amount of money of each house, return *the maximum amount of money you can rob tonight **without alerting the police***.

**Example 1:**

```
Input: nums = [2,3,2]
Output: 3
Explanation: You cannot rob house 1 (money = 2) and then rob house 3 (money = 2), because they are adjacent houses.
```

**Example 2:**

```
Input: nums = [1,2,3,1]
Output: 4
Explanation: Rob house 1 (money = 1) and then rob house 3 (money = 3).
Total amount you can rob = 1 + 3 = 4.
```

**Example 3:**

```
Input: nums = [1,2,3]
Output: 3
```

**Constraints:**

* `1 <= nums.length <= 100`
* `0 <= nums[i] <= 1000`

### Solution

#### Approach #0

```go
func rob(nums []int) int {
    n := len(nums)
    if n == 1 {
        return nums[0]
    }
    if n == 2 {
        return max(nums[0], nums[1])
    }
    return max(_rob(nums[:n-1]), _rob(nums[1:]))
}

func _rob(nums []int) int {
    first, second := nums[0], max(nums[0], nums[1])
    for _, num := range nums[2:] {
        first, second = second, max(first+num, second)
    }
    return second
}

func max(a, b int) int {
    if a > b {
        return a
    }
    return b
}
```

## [55. Jump Game](https://leetcode.com/problems/jump-game/)

### Description

You are given an integer array `nums`. You are initially positioned at the array's **first index**, and each element in the array represents your maximum jump length at that position.

Return `true` *if you can reach the last index, or* `false` *otherwise*.

**Example 1:**

```
Input: nums = [2,3,1,1,4]
Output: true
Explanation: Jump 1 step from index 0 to 1, then 3 steps to the last index.
```

**Example 2:**

```
Input: nums = [3,2,1,0,4]
Output: false
Explanation: You will always arrive at index 3 no matter what. Its maximum jump length is 0, which makes it impossible to reach the last index.
```

**Constraints:**

* `1 <= nums.length <= 10^4`
* `0 <= nums[i] <= 10^5`

### Solution

#### Approach #0

```go
func canJump(nums []int) bool {
    right := 0
    for i, num := range nums {
        if i > right {
            return false
        }
        right = max(right, i+num)
        if right >= len(nums)-1 {
            return true
        }
    }
    return false
}

func max(a, b int) int {
    if a > b {
        return a
    }
    return b
}
```

## [1037. Valid Boomerang](https://leetcode.com/problems/valid-boomerang/)

### Description

Given an array `points` where `points[i] = [xi, yi]` represents a point on the **X-Y** plane, return `true` *if these points are a **boomerang***.

A **boomerang** is a set of three points that are **all distinct** and **not in a straight line**.

**Example 1:**

```
Input: points = [[1,1],[2,3],[3,2]]
Output: true
```

**Example 2:**

```
Input: points = [[1,1],[2,2],[3,3]]
Output: false
```

**Constraints:**

* `points.length == 3`
* `points[i].length == 2`
* `0 <= x[i], y[i] <= 100`

### Solution

#### Approach #0

```go
func isBoomerang(points [][]int) bool {
    v1 := [2]int{points[1][0] - points[0][0], points[1][1] - points[0][1]}
    v2 := [2]int{points[2][0] - points[1][0], points[2][1] - points[1][1]}
    return v1[0]*v2[1]-v2[0]*v1[1] != 0
}
```
