今日头条2017秋季校招在线编程题解法参考

题目请移步到:http://blog.csdn.net/lzuacm/article/details/52699793


以下先写出我的解法

题目1: String Shifting

import java.util.Iterator;
import java.util.LinkedList;

public class Algorithm {
    static String str = "abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc";
    static int length = str.length();
    static char firstChar = str.charAt(0);
    static LinkedCharQueue base = new LinkedCharQueue(firstChar);
    static StringBuilder base2 = new StringBuilder(String.valueOf(firstChar));
    static LinkedList<LinkedCharQueue> queues = new LinkedList<LinkedCharQueue>();
    static LinkedList<StringBuilder> queues2 = new LinkedList<StringBuilder>();
    static int time;

    public static void main(String[] args) {
        StringBuilder sBuilder = new StringBuilder();

        for (int i = 1, num = 100000; i <= num; i++) {
            sBuilder.append(str);

            if (i % 10 == 0) {
                sBuilder.append('u');
            }

            if (i % 100 == 0) {
                sBuilder.append('t');
            }

            if (i % 1000 == 0) {
                sBuilder.append('w');
            }
        }

        //sBuilder.append('o');

        str = sBuilder.toString();
        length = str.length();

        System.out.println("length = " + length);

        long startTime = System.currentTimeMillis();

        compare();

        long endTime = System.currentTimeMillis();

        System.out.println(time + "  " + (endTime - startTime) + "ms");

        startTime = System.currentTimeMillis();

        compare2();

        endTime = System.currentTimeMillis();

        System.out.println(time + "  " + (endTime - startTime) + "ms");
    }

    private static boolean compare2() {
        boolean result;

        while (true) {
            int len = base2.length();
            time = queues2.size() + 1;
            int start = len * time;
            int end = start + len;

            if (start == length) {
                result = true;
                break;
            }

            if (end > length) {
                result = false;
                break;
            }

            char tmp = str.charAt(start);
            StringBuilder sb = new StringBuilder(String.valueOf(tmp));

            if (length % len != 0 || tmp != firstChar) {
                for (int pos = start + 1; pos < length; pos++) {
                    tmp = str.charAt(pos);

                    if (tmp == firstChar) {
                        break;
                    }

                    sb.append(tmp);
                }

                queues2.add(sb);
                merge2();

                continue;
            } else {
                boolean ret = true;

                for (int i = 1; i < len; i++) {
                    tmp = str.charAt(start + i);

                    if (tmp != base2.charAt(i)) {
                        ret = false;
                        break;
                    } else {
                        sb.append(tmp);
                    }
                }

                queues2.add(sb);

                if (!ret) {
                    merge2();
                }

                continue;
            }
        }

        return result;
    }

    private static void merge2() {
        Iterator<StringBuilder> iterator = queues2.iterator();

        while (iterator.hasNext()) {
            base2.append(iterator.next());
            iterator.remove();
        }
    }

    private static boolean compare() {
        boolean result;

        while (true) {
            /*
            System.out.println(base);
            
            for (LinkedCharQueue queue : queues) {
            	System.out.println(queue);
            }
            */

            int size = base.size();
            time = queues.size() + 1;
            int start = size * time;
            int end = start + size;

            if (start == length) {
                result = true;
                break;
            }

            if (end > length) {
                result = false;
                break;
            }

            char tmp = str.charAt(start);
            LinkedCharQueue newQueue = new LinkedCharQueue(tmp);

            if (length % size != 0 || tmp != base.next()) {
                for (int pos = start + 1; pos < length; pos++) {
                    tmp = str.charAt(pos);

                    if (tmp == firstChar) {
                        break;
                    }

                    newQueue.addChar(tmp);
                }

                queues.add(newQueue);
                merge();

                continue;
            } else {
                boolean ret = true;

                for (int pos = start + 1; pos < end; pos++) {
                    tmp = str.charAt(pos);

                    if (tmp != base.next()) {
                        ret = false;
                        break;
                    } else {
                        newQueue.addChar(tmp);
                    }
                }

                queues.add(newQueue);

                if (!ret) {
                    merge();
                } else {
                    base.rewind();
                }

                continue;
            }
        }

        return result;
    }

    private static void merge() {
        Iterator<LinkedCharQueue> iterator = queues.iterator();

        while (iterator.hasNext()) {
            base.addAll(iterator.next());
            iterator.remove();
        }
    }
}

class LinkedCharQueue {
    private static class Node {
        static final Node NEXT;

        static {
            NEXT = new Node('\0', true);
            NEXT.setNext(NEXT);
        }

        private char value;
        private Node next;

        private Node(char value, boolean bool) {
            this(value, null);
        }

        Node(char value) {
            this(value, NEXT);
        }

        Node(char value, Node next) {
            this.value = value;
            this.next = next;
        }

        Node setNext(Node next) {
            this.next = next;
            return next;
        }

        Node myNext() {
            return next;
        }
    }

    private int size;
    private final Node first;
    private Node last;
    private Node current;

    public LinkedCharQueue(char value) {
        first = last = new Node(value);
        size = 1;
    }

    public void rewind() {
        current = null;
    }

    private Node nodeNext() {
        if (current == null) {
            current = first;
        } else {
            current = current.myNext();
        }
        return current;
    }

    public char next() {
        return nodeNext().value;
    }

    private void addNode(Node node) {
        last = last.setNext(node);
        size++;
    }

    public void addChar(char value) {
        addNode(new Node(value));
    }

    public int size() {
        return size;
    }

    public void addAll(LinkedCharQueue another) {
        last.setNext(another.first);
        last = another.last;
        size += another.size;
        rewind();
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();

        rewind();

        for (int i = 0; i < size; i++) {
            sb.append(next()).append(" ");
        }

        rewind();

        return sb.toString();
    }
}

题目2: 字典序

public class Algorithm {
    static long[] timesSum = new long[19]; // ( > 0 且 < 10 ^ a ) 的数中,以某数字开头的数字的数量
    static long[] count = new long[10]; // 指定数字以下(包括该指定数字)的所有大于0的数字中,以a开头的数字的数量

    public static void main(String[] args) {
        for (int n = 1; n <= 18; n++) {
            timesSum[n] = ((long) (Math.pow(10, n) - 1) / 9);
        }

        long value = 489761654765465L;
        long index = 434206099209910L;
        String str = String.valueOf(value);
        int longness = str.length();
        int first = Integer.valueOf(str.charAt(0)) - 48;
        int digitm1 = longness - 1;
        long multiple = (long) Math.pow(10, digitm1);

        if (first > 0) { // 400
            long startsWithFirst = value % multiple + 1;
            count[first] += startsWithFirst;

            for (int n = 1; n <= 9; n++) { // 100
                count[n] += timesSum[digitm1];
            }

            for (int j = 1; j < first; j++) { // 100~399
                count[j] += multiple;
            }
        }

        long sum = 0;

        for (int i = 1; i <= 9; i++) {
            System.out.println(i + " : " + count[i]);

            sum += count[i];
        }

        System.out.println("sum = " + sum);

        sum = 0;
        int startNumber = 0;
        long secIndex = 0;

        for (int i = 1; i <= 9; i++) {
            sum += count[i];

            if (sum >= index) {
                System.out.println("sum = " + sum + ", index = " + index + " is between " + (i - 1) + " and " + i);
                secIndex = index - (sum - count[i]);
                startNumber = i;
                break;
            }
        }

        System.out.println("startNumber = " + startNumber + "  secIndex = " + secIndex);

        long thrIndex = 0;
        int digit = 1;

        for (; digit <= digitm1 + 1; digit++) {
            if (timesSum[digit] >= secIndex) {
                thrIndex = secIndex - timesSum[digit - 1];
                break;
            }
        }

        System.out.println("digit = " + digit + "  thrIndex = " + thrIndex);
        System.out.println("Number = " + (startNumber * (long) Math.pow(10, digit - 1) + (thrIndex - 1)));
    }
}

点赞