Javaアルゴリズム問題解法集

1. 文字頻度解析

問題概要

小文字英字のみで構成される単語が与えられます。最も頻繁に出現する文字とその回数を求めてください。複数の文字が同じ回数出現する場合は、辞書順で最小の文字を出力します。

実装例

import java.util.Scanner;

public class CharacterFrequency {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        String text = input.nextLine();
        int[] frequency = new int[26];
        
        for(int i = 0; i < text.length(); i++) {
            frequency[text.charAt(i) - 'a']++;
        }
        
        char resultChar = 'a';
        int maxCount = 0;
        for(int i = 0; i < 26; i++) {
            if(frequency[i] > maxCount) {
                maxCount = frequency[i];
                resultChar = (char)('a' + i);
            }
        }
        
        System.out.println(resultChar);
        System.out.println(maxCount);
        input.close();
    }
}

2. 成績統計計算

問題概要

学生の点数データから、合格率(60点以上)と優秀率(85点以上)を百分率で出力します。百分率の整数部分は四捨五入します。

実装例

import java.util.Scanner;

public class ScoreStatistics {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int studentCount = scanner.nextInt();
        double passCount = 0;
        double excellentCount = 0;
        
        for(int i = 0; i < studentCount; i++) {
            int score = scanner.nextInt();
            if(score >= 60) {
                passCount++;
                if(score >= 85) {
                    excellentCount++;
                }
            }
        }
        
        System.out.println(Math.round(passCount * 100 / studentCount) + "%");
        System.out.println(Math.round(excellentCount * 100 / studentCount) + "%");
        scanner.close();
    }
}

3. 数値カード制限

問題概要

数字カード(0-9)を各2021枚持っています。1から順に数字を組み立てていき、カードが不足する直前の数値を求めます。

実装例

public class CardLimit {
    public static void main(String[] args) {
        int oneCount = 0;
        for(int i = 1; i < 20210; i++) {
            String numStr = Integer.toString(i);
            for(int j = 0; j < numStr.length(); j++) {
                if(numStr.charAt(j) == '1') {
                    oneCount++;
                }
            }
            if(oneCount > 2021) {
                System.out.println(i - 1);
                break;
            }
        }
    }
}

4. メモリ容量計算

問題概要

256MBのメモリ空間に32ビット整数を格納する場合、最大何個格納できるかを計算します。

実装例

public class MemoryCapacity {
    public static void main(String[] args) {
        long result = 256L * 1024 * 1024 * 8 / 32;
        System.out.println(result);
    }
}

5. グリッド経路探索

問題概要

n×mのグリッド上で、現在位置より右下方向のみに移動可能で、一度の移動距離は最大3マスです。左上から右下まで移動した時の最大権利値を求めます。

実装例

import java.util.Scanner;

public class GridPath {
    static int[][] grid;
    static int rows, cols;
    static int maxSum = Integer.MIN_VALUE;
    static int[] moveX = {0,0,0,1,1,1,2,2,3};
    static int[] moveY = {1,2,3,0,1,2,0,1,0};
    
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        rows = sc.nextInt();
        cols = sc.nextInt();
        grid = new int[rows][cols];
        
        for(int i = 0; i < rows; i++) {
            for(int j = 0; j < cols; j++) {
                grid[i][j] = sc.nextInt();
            }
        }
        
        explore(0, 0, grid[0][0]);
        System.out.println(maxSum);
        sc.close();
    }
    
    static void explore(int x, int y, int currentSum) {
        if(x == rows - 1 && y == cols - 1) {
            maxSum = Math.max(maxSum, currentSum);
            return;
        }
        
        for(int k = 0; k < moveX.length; k++) {
            int nextX = x + moveX[k];
            int nextY = y + moveY[k];
            if(nextX < rows && nextY < cols && nextX >= x && nextY >= y) {
                explore(nextX, nextY, currentSum + grid[nextX][nextY]);
            }
        }
    }
}

6. 直方体配置パターン

問題概要

与えられた数値nを3つの正の整数の積で表す方法が何通りあるかを求めます(L×W×H = n)。

実装例

import java.util.*;

public class FactorizationCount {
    public static void main(String[] args) {
        long target = 2021041820210418L;
        List<Long> divisors = new ArrayList<>();
        
        for(long i = 1; i * i <= target; i++) {
            if(target % i == 0) {
                divisors.add(i);
                if(target / i != i) {
                    divisors.add(target / i);
                }
            }
        }
        
        int combinationCount = 0;
        for(long a : divisors) {
            for(long b : divisors) {
                for(long c : divisors) {
                    if(a * b * c == target) {
                        combinationCount++;
                    }
                }
            }
        }
        
        System.out.println(combinationCount);
    }
}

7. ミリ秒から時刻変換

問題概要

1970年1月1日からの経過ミリ秒をHH:MM:SS形式の時刻に変換します。

実装例

import java.util.Scanner;

public class TimeConverter {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        long milliseconds = sc.nextLong();
        sc.close();
        
        long totalSeconds = milliseconds / 1000;
        long seconds = totalSeconds % 60;
        
        long totalMinutes = totalSeconds / 60;
        long minutes = totalMinutes % 60;
        
        long totalHours = totalMinutes / 60;
        long hours = totalHours % 24;
        
        String time = String.format("%02d:%02d:%02d", hours, minutes, seconds);
        System.out.println(time);
    }
}

8. グラフ最短経路

問題概要

異なる重みを持つ辺からなる無向グラフで、指定された2点間の最短距離を求めます。

実装例

import java.util.*;

public class ShortestPath {
    public static void main(String[] args) {
        List edges = new ArrayList<>();
        // 辺の追加処理
        addEdge(edges, 'A', 'C', 1);
        // ... 他の辺を追加
        
        int[] distance = new int[128];
        Arrays.fill(distance, Integer.MAX_VALUE / 2);
        distance['A'] = 0;
        
        for(int i = 0; i < edges.size() - 1; i++) {
            for(int[] edge : edges) {
                int u = edge[0], v = edge[1], w = edge[2];
                distance[v] = Math.min(distance[v], distance[u] + w);
            }
        }
        
        System.out.println(distance['S']);
    }
    
    static void addEdge(List edgeList, char u, char v, int weight) {
        edgeList.add(new int[]{u, v, weight});
        edgeList.add(new int[]{v, u, weight});
    }
}

9. 回文日付探索

問題概要

指定された日付以降で、回文日付とABABBABA型の回文日付をそれぞれ求めます。

実装例

import java.util.*;
import java.text.SimpleDateFormat;

public class PalindromeDate {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int startDate = sc.nextInt();
        boolean foundNormal = false, foundSpecial = false;
        
        for(int year = startDate / 10000; !foundNormal || !foundSpecial; year++) {
            String yearStr = Integer.toString(year);
            StringBuffer reverse = new StringBuffer(yearStr).reverse();
            String dateStr = yearStr + reverse.toString();
            
            if(!foundNormal && isValidDate(dateStr) && Integer.parseInt(dateStr) > startDate) {
                System.out.println(dateStr);
                foundNormal = true;
            }
            
            if(!foundSpecial && isValidDate(dateStr) && Integer.parseInt(dateStr) > startDate 
               && dateStr.substring(0, 2).equals(dateStr.substring(2, 4))) {
                System.out.println(dateStr);
                foundSpecial = true;
            }
        }
        sc.close();
    }
    
    static boolean isValidDate(String date) {
        try {
            String formatted = date.substring(0,4) + "-" + date.substring(4,6) + "-" + date.substring(6,8);
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            sdf.setLenient(false);
            sdf.parse(formatted);
            return true;
        } catch (Exception e) {
            return false;
        }
    }
}

10. 数字カウント問題

問題概要

1から2020までの数字の中で、数字2が何回出現するかを数えます。

実装例

public class DigitCounter {
    public static void main(String[] args) {
        int totalCount = 0;
        for(int i = 1; i <= 2020; i++) {
            int number = i;
            while(number > 0) {
                if(number % 10 == 2) {
                    totalCount++;
                }
                number /= 10;
            }
        }
        System.out.println(totalCount);
    }
}

タグ: Java アルゴリズム データ構造 文字列処理 数値計算

8月9日 12:52 投稿