剑指Offer之java版

题目1:设计一个类,我们只能生成该类的一个实例
//双检锁/双重校验锁(DCL,即 double-checked locking)
public class Singleton {
private volatile static Singleton sInstance = null;

private Singleton() {

}

public static Singleton getInstance() {
    if (sInstance == null) {
        synchronized (Singleton.class) {
            if (sInstance == null) {
                sInstance = new Singleton();
            }
        }
    }
    return  sInstance;
}
}
题目2:找出数组中的重复数字,时间复杂度O(n)
//对于一维数组排序满足O(n)时间复杂度,优先考虑hashmap
private static int findDuplicateNumber(int[] list) {
    int number = -1;
    //以数组的数作为key,如果key有重复,value递增
    HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
    for (int i=0; i<list.length; i++) {
        if (map.containsKey(list[i])) {
            map.put(list[i], map.get(list[i]) + 1);
        } else {
            map.put(list[i], 1);
        }
    }

    //便利hashmap,找出value大于1对应的key值
    for (Map.Entry<Integer, Integer> entry: map.entrySet()) {
        if (entry.getValue() > 1) {
            number = entry.getKey();
        }
    }
    return number;
}
题目3:实现一个函数,把字符串每中的每个空格替换成“%20”。例如输入“we are happy.”,则输出“we%20are%20happy.”
public static void main (String[] args) {
    String str = "We are happy!";
    replaceBlank(str.toCharArray());
}

private static void replaceBlank(char[] arr) {
    int count = 0;
    int lenth = 0;
    //计算新数组长度,等于原长度加上空格数*2
    for (int i=0; i<arr.length; i++) {
        if (arr[i] == ' ') {
            count ++;
        }
    }
    lenth = arr.length + count * 2;

    //设置两个指针p1,p2,如果p1遇到空格,p2 后三位赋值%20,p1后移一位
    char[] list = new char[lenth];
    int p1=0, p2=0; //p1原数组指针,p2 新数组指针
    while (p1<arr.length && p2<lenth) {
        if (arr[p1] == ' ') {
            list[p2++] = '%';
            list[p2++] = '2';
            list[p2++] = '0';
            p1++;
        } else {
            list[p2++] = arr[p1++];
        }
    }
    System.out.print(String.valueOf(list));
}
题目4:有两个排序的数组A1和A2,内存在A1的末尾有足够多的空余空间容纳A2.请实现一个函数,把A2中的所有数字插入A1中,并且所有的数字是排序的。
public static void main(String[] args) {
    int[] A1 = {1, 3, 6, 7, 10, 23};
    int[] A2 = {2, 6, 8, 24};
    merged(A1, A2);
}

private static void merged(int[] A1, int[] A2) {
    int indexA1 = A1.length - 1;
    int indexA2 = A2.length - 1;
    int mergedIndex = A1.length + A2.length - 1;
    int[] mergedA = new int[A1.length + A2.length];
    //从后往前插入,也可以从前往后插入
    while (indexA1>=0 && indexA2>=0) {
        if (A1[indexA1] >= A2[indexA2]) {
            mergedA[mergedIndex--] = A1[indexA1--];
        } else {
            mergedA[mergedIndex--] = A2[indexA2--];
        }
    }

    while (indexA1>=0) {
        mergedA[mergedIndex--] = A1[indexA1--];
    }

    while (indexA2>=0) {
        mergedA[mergedIndex--] = A2[indexA2--];
    }

    for(int i=0; i<mergedA.length; i++) {
        System.out.print(mergedA[i] + ", ");
    }
}
题目5:输入一个链表的头结点,从尾到头反过来打印每个节点的值
//链表节点定义
static class ListNode {
    int data;
    ListNode next;
}

public static void main(String[] args) {
    ListNode listNode = new ListNode();
    ListNode listNode2 = new ListNode();
    ListNode listNode3 = new ListNode();
    ListNode listNode4 = new ListNode();
    ListNode listNode5 = new ListNode();

    listNode.data = 1;
    listNode.next = listNode2;

    listNode2.data = 5;
    listNode2.next = listNode3;

    listNode3.data = 10;
    listNode3.next = listNode4;

    listNode4.data = 15;
    listNode4.next = listNode5;

    listNode5.data = 20;

    //打印链表
    printListNode(listNode);

    System.out.print("\n----------------------------\n");

    //使用堆反向打印链表
    printListReversByStack(listNode);

    System.out.print("\n----------------------------\n");

    //使用递归反向打印堆栈
    printListReversByRecursive(listNode);
}

//顺序打印链表
private static void printListNode(ListNode node) {
    if (node == null) {
        return;
    }

    while (node != null) {
        System.out.print(node.data);
        node = node.next;
        if (node != null) {
            System.out.print(" --> ");
        }
    }
}

//使用堆反向打印链表
private static void printListReversByStack(ListNode node) {
    Stack<ListNode> stack = new Stack<ListNode>();

    while (node != null) {
        stack.push(node);
        node = node.next;
    }

    while (!stack.isEmpty()) {
        System.out.print(stack.pop().data);

        if (!stack.isEmpty()) {
            System.out.print(" --> ");
        }
    }
}

//使用递归反向打印堆栈
private static void printListReversByRecursive(ListNode node) {
    if (node != null) {
        if (node.next != null) {
            printListReversByRecursive(node.next);
        }
    }

    System.out.print(node.data);
}
题目5:重构二叉树
public static class BinaryTreeNode {
    int value;
    BinaryTreeNode left;
    BinaryTreeNode right;
}

public  static  void  main(String[] args) {
    int[] preOrder = {1,2,4,7,3,5,6,8};
    int[] inOrder={4,7,2,1,5,3,8,6};
    BinaryTreeNode node = reConstruct( preOrder, inOrder );
    printTree( node );
}

private static BinaryTreeNode reConstruct (int[] prOrder, int[] inOrder) {
    if (prOrder == null || inOrder == null || prOrder.length != inOrder.length || prOrder.length < 1) {
        return  null;
    }
    return constrct(prOrder, 0, prOrder.length-1, inOrder, 0, inOrder.length-1);
}

/*
*  @param preOrder 前序遍历序列
*  @param preBegin 前序遍历开始位置
*  @param preEnd 前序遍历结束位置
*  @param inOrder 中序遍历序列
*  @param inBegin 中序遍历序列开始位置
*  @param inEnd 中序遍历序列结束位置
* */
private static BinaryTreeNode constrct (int[] preOrder, int preBegin, int preEnd, int[] inOrder, int inBegin, int inEnd) {
    if (preBegin > preEnd) return  null;

    int root = preOrder[preBegin];
    int index = inBegin;

    while (index <= inEnd && inOrder[index] != root) {
        index ++;
    }

    if (index > inEnd) {
        throw new RuntimeException( "invalid input index: " + index);
    }

    BinaryTreeNode node = new BinaryTreeNode();
    node.value = root;
    node.left = constrct( preOrder, preBegin+1, preBegin+index-inBegin, inOrder, inBegin, index-1 );
    node.right =  constrct( preOrder, preBegin+index-inBegin+1, preEnd, inOrder, index+1, inEnd );
    return  node;
}

/*
* 中序遍历递归打印
* */
private static void printTree (BinaryTreeNode node) {
    if (node != null) {
        printTree( node.left );
        System.out.print( node.value + " " );
        printTree( node.right );
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容