剑指Offer(Java实现):调整数组顺序使奇数位于偶数前面 + 链表中倒数第k个节点 + 链表中环的入口节点 + 反转链表

package com.dengzm.jianzhioffer;

/**
 * @Description 021 调整数组顺序使奇数位于偶数前面
 * Created by deng on 2018/12/22.
 */
public class Jianzhi021 {

    public static void main(String[] args) {
        recordOddEven(new int[] {1,2,3,4,5,6});
    }

    private static void recordOddEven(int[] data) {
        if (data == null || data.length == 0) {
            return;
        }

        int start = 0;
        int end  = data.length - 1;
        int temp;

        while (start < end) {
            while (start < end && (data[start] & 0x1) != 0) {
                start ++;
            }
            while (start < end && (data[end] & 0x1) == 0) {
                end --;
            }
            if (start < end) {
                temp = data[start];
                data[start] = data[end];
                data[end] = temp;
            }
        }

        for (int i = 0; i < data.length; i ++) {
            System.out.println(data[i]);
        }
    }

}

package com.dengzm.jianzhioffer;

/**
 * @Description 链表中倒数第k个节点
 * Created by deng on 2019/1/6.
 */
public class Jianzhi022 {
    public static void main(String[] args) {
        Node head = new Node(1);
        Node temp1 = new Node(2);
        Node temp2 = new Node(3);
        Node temp3 = new Node(4);
        Node temp4 = new Node(5);
        head.next = temp1;
        temp1.next = temp2;
        temp2.next = temp3;
        temp3.next = temp4;
        findLastKNode(head, 6);
        findLastKNode(head, 3);
        findLastKNode(head, 1);
    }

    private static void findLastKNode(Node head, int k) {
        if (head == null || k < 1) {
            return;
        }
        // 两个指针,first先走k步,然后一起移动;当first到达尾部时,second即为倒数第k个。
        // 需要注意的是,第一个指针向后移动k次,会不会超过链表长度?
        Node first = head;
        Node second = head;

        if (k != 1) {
            for (int i = 0; i < k - 1; i ++) {
                first = first.next;
                if (first == null) {
                    System.out.println("链表长度为" + (i + 1) + ", 长度不够!");
                    return;
                }
            }
        }

        while (first.next != null) {
            first = first.next;
            second = second.next;
        }
        System.out.println(second.value);
    }

    static class Node {
        Node next;
        int value;

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

package com.dengzm.jianzhioffer;

/**
 * @Description 链表中环的入口节点
 * Created by deng on 2019/1/6.
 */
public class Jianzhi023 {
    public static void main(String[] args) {
        //无环
        Node head = new Node(1);
        Node temp1 = new Node(2);
        Node temp2 = new Node(3);
        Node temp3 = new Node(4);
        Node temp4 = new Node(5);
        head.next = temp1;
        temp1.next = temp2;
        temp2.next = temp3;
        temp3.next = temp4;
        findEntryOfLoop(head);

        //有环
        Node ahead = new Node(1);
        Node atemp1 = new Node(2);
        Node atemp2 = new Node(3);
        Node atemp3 = new Node(4);
        Node atemp4 = new Node(5);
        ahead.next = atemp1;
        atemp1.next = atemp2;
        atemp2.next = atemp3;
        atemp3.next = atemp4;
        atemp4.next = atemp2;
        findEntryOfLoop(ahead);
    }

    private static void findEntryOfLoop(Node head) {
        if (head == null) {
            return;
        }

        // 获取环内节点个数:first向前num步,当second到达入口节点时,first绕环一圈也回到了入口节点
        int num = isLoop(head);

        if (num == 0) {
            System.out.println("this is not a loop!");
            return;
        }

        Node first = head;
        Node second = head;

        for (int i = 0; i < num; i ++) {
            first = first.next;
        }

        while (first != second) {
            first = first.next;
            second = second.next;
        }

        System.out.println(first.value);
    }

    /**
     * 判断当前链表是否为loop
     * @param head 头节点
     * @return 是,返回环内节点个数;否,返回0
     */
    private static int isLoop(Node head) {
        Node first = head;
        Node second = head;
        int num = 0;

        do {
            first = first.next;
            if (first == null) {
                return 0;
            }
            first = first.next;
            second = second.next;
            num ++;
        } while (first != null && first != second);

        return num;
    }

    static class Node {
        Node next;
        int value;

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

package com.dengzm.jianzhioffer;

/**
 * @Description 024 反转链表
 * Created by deng on 2019/1/6.
 */
public class Jianzhi024 {
    public static void main(String[] args) {
        Node head = new Node(1);
        Node temp1 = new Node(2);
        Node temp2 = new Node(3);
        Node temp3 = new Node(4);
        Node temp4 = new Node(5);
        head.next = temp1;
        temp1.next = temp2;
        temp2.next = temp3;
        temp3.next = temp4;
        reverseList(head);
    }

    private static void reverseList(Node head) {
        if (head == null) {
            return;
        }

        Node preNode = null;
        Node curNode = null;
        Node nextNode = head;

        while (nextNode != null) {
            curNode = nextNode;
            nextNode = nextNode.next;
            curNode.next = preNode;
            preNode = curNode;
        }

        while (curNode != null) {
            System.out.println(curNode.value);
            curNode = curNode.next;
        }
    }

    static class Node {
        Node next;
        int value;

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

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值