Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 115 additions & 0 deletions Algorithm/Other/leetcode/7. Reverse Integer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
この解法は、64ビット整数を使わずに、32ビット整数の範囲を超えないかを都度チェックしながら桁を逆にしていきます。

---

### ✅ TypeScriptコード(`fs`での入力読み取り対応)

```ts
import * as fs from 'fs';

const input = fs.readFileSync('/dev/stdin', 'utf8').trim();
const x = parseInt(input);

/**
* 32ビット整数の範囲
*/
const INT_MIN = -(2 ** 31);
const INT_MAX = 2 ** 31 - 1;

function reverse(x: number): number {
let result = 0;
let num = x;

while (num !== 0) {
const digit = num % 10 | 0; // 小数点対策で |0 して整数化
num = (num / 10) | 0;

// resultが次の桁を追加したときにオーバーフローしないか確認
if (
result > Math.floor(INT_MAX / 10) ||
(result === Math.floor(INT_MAX / 10) && digit > 7)
) {
return 0;
}
if (
result < Math.ceil(INT_MIN / 10) ||
(result === Math.ceil(INT_MIN / 10) && digit < -8)
) {
return 0;
}

result = result * 10 + digit;
}

return result;
}

console.log(reverse(x));
```

---

### 🔍 処理概要(図付きで説明)

たとえば `x = -123` のとき:

```
初期状態: result = 0, num = -123

ループ1:
digit = -123 % 10 = -3
num = -123 / 10 = -12
result = 0 * 10 + (-3) = -3

ループ2:
digit = -12 % 10 = -2
num = -12 / 10 = -1
result = -3 * 10 + (-2) = -32

ループ3:
digit = -1 % 10 = -1
num = -1 / 10 = 0
result = -32 * 10 + (-1) = -321

終了(num === 0)→ return -321
```

---

### 🛑 オーバーフローの例

例:`x = 1534236469`

```
途中で result = 964632435 になり、
次の桁(9)を追加すると 9646324350 + 9 = 9646324359 > INT_MAX
→ return 0
```

---

### ✅ テストケース例

```plaintext
Input:
123
Output:
321

Input:
-123
Output:
-321

Input:
120
Output:
21

Input:
1534236469
Output:
0
```

---
40 changes: 40 additions & 0 deletions Algorithm/Other/leetcode/7. Reverse Integer/ReverseInteger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import * as fs from 'fs';

const input = fs.readFileSync('/dev/stdin', 'utf8').trim();
const x = parseInt(input);

/**
* 32ビット整数の範囲
*/
const INT_MIN = -(2 ** 31);
const INT_MAX = 2 ** 31 - 1;

function reverse(x: number): number {
let result = 0;
let num = x;

while (num !== 0) {
const digit = num % 10 | 0; // 小数点対策で |0 して整数化
num = (num / 10) | 0;

// resultが次の桁を追加したときにオーバーフローしないか確認
if (
result > Math.floor(INT_MAX / 10) ||
(result === Math.floor(INT_MAX / 10) && digit > 7)
) {
return 0;
}
if (
result < Math.ceil(INT_MIN / 10) ||
(result === Math.ceil(INT_MIN / 10) && digit < -8)
) {
return 0;
}

result = result * 10 + digit;
}

return result;
}

console.log(reverse(x));
126 changes: 126 additions & 0 deletions DataStructures/Trees/BinaryIndexedTree/FenwickTree/atcoder/A76/A76.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package main

import (
"bufio"
"fmt"
"os"
"sort"
"strconv"
)

const MOD = 1_000_000_007

type FenwickTree struct {
n int
data []int
}

func NewFenwickTree(n int) *FenwickTree {
return &FenwickTree{
n: n,
data: make([]int, n+2),
}
}

func (ft *FenwickTree) Add(i, x int) {
i++
for i <= ft.n+1 {
ft.data[i] = (ft.data[i] + x) % MOD
i += i & -i
}
}

func (ft *FenwickTree) Sum(i int) int {
i++
res := 0
for i > 0 {
res = (res + ft.data[i]) % MOD
i -= i & -i
}
return res
}

func (ft *FenwickTree) RangeSum(l, r int) int {
return (ft.Sum(r) - ft.Sum(l-1) + MOD) % MOD
}

func lowerBound(a []int, x int) int {
return sort.Search(len(a), func(i int) bool { return a[i] >= x })
}

func upperBound(a []int, x int) int {
return sort.Search(len(a), func(i int) bool { return a[i] > x })
}

func main() {
scanner := bufio.NewScanner(os.Stdin)
scanner.Split(bufio.ScanWords) // 単語(スペース区切り)単位で読み取り

readInt := func() int {
scanner.Scan()
n, _ := strconv.Atoi(scanner.Text())
return n
}

N := readInt()
W := readInt()
L := readInt()
R := readInt()

X := make([]int, N)
for i := 0; i < N; i++ {
X[i] = readInt()
}

// 全地点(スタート0、足場、ゴールW)をリストアップ
positions := append([]int{0}, X...)
positions = append(positions, W)
sort.Ints(positions)

posIndex := make(map[int]int)
for i, v := range positions {
posIndex[v] = i
}

n := len(positions)
dp := make([]int, n)
dp[0] = 1

ft := NewFenwickTree(n)
ft.Add(0, 1)

for i := 1; i < n; i++ {
cur := positions[i]
left := cur - R
right := cur - L

li := lowerBound(positions, left)
ri := upperBound(positions, right) - 1

if li <= ri {
val := ft.RangeSum(li, ri)
dp[i] = val
ft.Add(i, val)
}
}

fmt.Println(dp[n-1])
}

// Go 解法で 20件の入力で ランタイムエラー(panic) が発生するとのこと、原因として考えられるのは以下のいずれかです:

// ❗️ 原因候補
// bufio.Scanner の 2行しか読んでいない
// 実際には N が大きくなると 複数行に分かれて入力される 可能性がある。
// つまり "5 65 7 37" の次に "5 15 30 50 55" でなく、改行を含む複数行に X が分割されている可能性がある。
// Xstr := strings.Fields(scanner.Text()) だけで全 N 要素を取得できない。

// ✅ 修正方針
// N 個の X[i] を読み切るまで ループで scanner.Scan() を繰り返す
// X := make([]int, N) を安全に埋める

// ✅ 修正点まとめ
// 修正箇所 内容
// scanner.Split(...) 単語単位で int を逐次読み取り可能に
// readInt() 関数 scanner.Scan() + strconv.Atoi() のラッパー
// X[i] = readInt() 必ず N 件読み切るようループで読み取り
Loading