617. Merge Two Binary Trees

LeetCode の挑戦ログ

Problem

https://leetcode.com/problems/merge-two-binary-trees/

  • 2つのバイナリツリーを同階層でマージしたツリーを作る

Solution

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public TreeNode mergeTrees(TreeNode t1, TreeNode t2) {
        return merge(t1, t2);
    }

    private TreeNode merge(TreeNode t1, TreeNode t2) {
        if (t1 == null && t2 == null) {
            return null;
        }

        int mergedVal = (t1 == null ? 0 : t1.val) + (t2 == null ? 0 : t2.val);
        TreeNode merged = new TreeNode(mergedVal);

        merged.left = merge(
                (t1 == null ? null : t1.left),
                (t2 == null ? null : t2.left)
        );
        merged.right = merge(
                (t1 == null ? null : t1.right),
                (t2 == null ? null : t2.right)
        );

        return merged;
    }
}

Impressions

  • 再帰処理はかなり頭を使わないと書けない
  • null チェックが美しさに欠ける(がどうすればいいものか)

自分の欠点を3つあげるとしたら

転職活動の面接で、「自分の欠点を3つあげるとしたらなんですか?」と聞かれたことがあった。

自分と向き合えるいい質問だなぁと思ったのと、後で見直したら面白そうなので記録しておく。

ちなみに面接の相手は開発者じゃなかったので、技術的な観点では答えていない。

目的の分からない作業ができない

「何のためにやるのか」が自分の中で明確になっていない作業ができない。

これは「目的を明確にしよう」みたいな綺麗事ではなくて。

お仕事なので、実際のところ手は動かすと思うんだけど、本当に著しくパフォーマンスが落ちる。

緊急のときなんか、は仕方なく説明を省略してとりあえず作業を終わらせたい時はあると思う。

でもそういう場面に弱い。

「やりたいことしかやらない」タイプではないけれど、「なぜやるかは納得してやりたい」気質が影響していると思う。

瞬発力や爆発力はない

完全にコツコツ型なので、一時的に負荷を上げて馬力を出すのは苦手。

昔は多少できた気もするが、意識的にコツコツ型へ移行したこともあり、今はあまりできる気がしない。

コミュニケーションが冗長

コミュニケーションをとる際に、できるだけコンテキストを共有したい思いがある。

これは自分がそうだから、人にもそうしようとしているからではある。

ただそれゆえ説明が過度になったり、時に冗長なことはあると思う。

場合によっては相手のコンテキストにも思いを馳せたりするので。

HTML5/CSS3 モダンコーディング を読んだ

HTML や CSS はデザイナーさんがマークアップまでしてくれることが多かったのだけれど、そういえば分からないことたくさんあるなぁと思って読んでみた。

サンプルサイトを写経しながら実際に作っていける。

最初に構造を決めてから組み上げていく流れになっていて、とても分かりやすい。

正直良く分からないテクニックみたいなのもあったんだけど、真似して書けばとりあえずページは出来上がるので、モチベーションが続きやすい。

これでマークアップができるようになる気は全くしないが、この本を取っ掛かりにすれば手を伸ばしていけそうな気持ちになる。

HTML5/CSS3 モダンコーディング 読書メモ · GitHub

657. Robot Return to Origin

LeetCode の挑戦ログ

Problem

https://leetcode.com/problems/robot-return-to-origin/

  • 座標位置を上下左右に動かす指示が文字列で与えられる
    • R (right), L (left), U (up), and D (down)
  • 元の位置 (0, 0) に戻っていたら true , 戻っていなければ false を返す

Solution

class Solution {
    public boolean judgeCircle(String moves) {
        int x = 0;
        int y = 0;
        for (int i = 0; i < moves.length(); i++) {
            switch (moves.charAt(i)) {
                case 'R':
                    x++;
                    break;
                case 'L':
                    x--;
                    break;
                case 'U':
                    y++;
                    break;
                case 'D':
                    y--;
                    break;
                default:
                    break;
            }
        }
        return x == 0 && y == 0;
    }
}

Impressions

  • 愚直に動かすアプローチを取った
    • false と分かった時点で return するアプローチもいくつかありそう
    • 文字列長が奇数ならそもそも false とか
    • RL と UD みたいに対比するコマンドの数が合わないとか
  • switch 文の書き方をよく忘れる

A - Remaining Balls

AtCoder の挑戦ログ

Problem

https://atcoder.jp/contests/abc154/tasks/abc154_a

Solution

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        String color1 = sc.next();
        sc.next();
        int color1Cnt = sc.nextInt();
        int color2Cnt = sc.nextInt();
        String disposed = sc.next();

        if (disposed.equals(color1)) {
            System.out.printf("%d %d", color1Cnt - 1, color2Cnt);
            return;
        }
        System.out.printf("%d %d", color1Cnt, color2Cnt - 1);
    }
}

Impressions

  • LeetCode と違って標準入出力から自分で書かなきゃいけないのが面倒
  • 簡単な問題なら戦えそうなので、コンテスト出てみようかな

728. Self Dividing Numbers

LeetCode の挑戦ログ

Problem

https://leetcode.com/problems/self-dividing-numbers/

  • 整数の範囲が渡される
  • 範囲の中から、自身の桁ごとの数字で割り切れる値を抽出する
  • 0 を含む値は除外する

Solution

class Solution {
    public List<Integer> selfDividingNumbers(int left, int right) {
        return IntStream.range(left, right + 1)
                .mapToObj(DividingNumber::new)
                .filter(DividingNumber::isSelfDividingNumber)
                .map(DividingNumber::getValue)
                .collect(Collectors.toList());
    }
}

class DividingNumber {
    private int value;

    DividingNumber(int value) {
        this.value = value;
    }

    boolean isSelfDividingNumber() {
        return Arrays.stream(split(value)).allMatch(i -> i != 0 && this.value % i == 0);
    }

    int getValue() {
        return value;
    }

    private int[] split(int num) {
        String s = String.valueOf(num);
        int[] split = new int[s.length()];
        for (int i = 0; i < s.length(); i++) {
            split[i] = Character.getNumericValue(s.charAt(i));
        }
        return split;
    }

    @Override
    public String toString() {
        return "DividingNumber{" +
                "value=" + value +
                '}';
    }
}

Impressions

  • 元の値と桁ごとの値を同時に扱うようにしたので、箱としてクラスを作った
  • 範囲用に Stream#range がある
  • allMatch の存在を忘れて filter と count でどうにかしようとしちゃう

627. Swap Salary

LeetCode の挑戦ログ

Problem

https://leetcode.com/problems/swap-salary/

  • salary テーブルの性別を入れ替える
  • f の行は m に
  • m の行は f に

Solution

UPDATE salary SET sex = (
  CASE 
    WHEN sex = 'f' THEN 'm'
    ELSE 'f'
  END
);

Impressions

  • CASE 文便利