《剑指offer第二版》四

1. 表示数值的字符串

(1)题目描述

请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100"、“5e2”、"-123"、“3.1416”、“0123"及”-1E-16"都表示数值,但"12e"、“1a3.14”、“1.2.3”、"±5"及"12e+5.4"都不是。

(2)题目分析

本题的解法比较中规中矩,只需要考虑好可能出现情况即可,通过设置三个标志位,即numSeen,eSeen,dotSeen,当e出现后,不允许再出现e,±号只能出现在第一位和e的后面一位,点也只能出现在e的前面,并且只能出现一次。

(3)代码

package swordOffer.day4;

/**
 * @author chengzhengda
 * @version 1.0
 * @date 2020-03-24 10:59
 * @desc
 */
public class t16 {

    public static boolean isNumber(String s) {
        if (s == null || s.length() == 0) {
            return false;
        }
        boolean numSeen = false;
        boolean dotSeen = false;
        boolean eSeen = false;
        s = s.trim();
        for (int i = 0; i < s.length(); i++) {
            if (s.charAt(i) >= '0' && s.charAt(i) <= '9') {
                numSeen = true;
            } else if (s.charAt(i) == '.') {
                if (dotSeen || eSeen) {
                    return false;
                }
                dotSeen = true;
            } else if (s.charAt(i) == 'e' || s.charAt(i) == 'E') {
                if (eSeen || !numSeen) {
                    return false;
                }
                eSeen = true;
                numSeen = false;
            } else if (s.charAt(i) == '-' || s.charAt(i) == '+') {
                if (i != 0 && s.charAt(i - 1) != 'e' && s.charAt(i - 1) != 'E') {
                    return false;
                }
            } else {
                return false;
            }
        }
        return numSeen;
    }

    public static void main(String[] args) {
        System.out.println(isNumber("1 "));
    }
}

2. 调整数组顺序使奇数位于偶数前面

(1)题目描述

输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。

示例:
输入:nums = [1,2,3,4]
输出:[1,3,2,4]
注:[3,1,2,4] 也是正确的答案之一。

(2)题目分析

本题比较简单的解法是新建一个数组,然后依次将数字放入数组中,但是这样会有额外的空间消耗,因此最优解是通过设置头尾双指针,然后遍历,通过交换头尾的数字,来实现。

(3)代码

package swordOffer.day4;

/**
 * @author chengzhengda
 * @version 1.0
 * @date 2020-03-24 15:23
 * @desc
 */
public class t17 {

    public static int[] exchange(int[] nums) {
        int i = 0;
        int j = nums.length - 1;

        while (i < j) {
            if (nums[i] % 2 != 0) {
                i++;
                continue;
            }
            if (nums[j] % 2 == 0) {
                j--;
                continue;
            }

            int temp = nums[j];
            nums[j] = nums[i];
            nums[i] = temp;
            i++;
            j--;
        }
        return nums;
    }

    public static void main(String[] args) {
        int[] nums = {1, 3, 4, 5, 6, 7, 8};
        exchange(nums);
    }
}

3. 链表中倒数第k个节点

(1)题目描述

输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。例如,一个链表有6个节点,从头节点开始,它们的值依次是1、2、3、4、5、6。这个链表的倒数第3个节点是值为4的节点。

示例:
给定一个链表: 1->2->3->4->5, 和 k = 2.
返回链表 4->5.

(2)题目分析

本题通过设置快慢指针,当指针A走了k步后,指针B才开始走,这样指针AB之间刚好距离k步,当指针A走到终点时,指针B刚好走到倒数第k步。

(3)代码

package swordOffer.day4;

import charpter2.ListNode;

/**
 * @author chengzhengda
 * @version 1.0
 * @date 2020-03-24 17:14
 * @desc
 */
public class t18 {
    public static ListNode getKthFromEnd(ListNode head, int k) {
        ListNode fast = head;
        ListNode slow = head;
        int i = 0;
        while (fast != null) {
            if (i >= k) {
                slow = slow.next;
            }
            fast = fast.next;
            i++;
        }
        return slow;
    }

    public static void main(String[] args) {
        ListNode listNode1 = new ListNode(1);
        ListNode listNode2 = new ListNode(2);
        ListNode listNode3 = new ListNode(3);
        ListNode listNode4 = new ListNode(4);
        listNode1.next = listNode2;
        listNode2.next = listNode3;
        listNode3.next = listNode4;
        System.out.println(getKthFromEnd(listNode1, 2).val);
    }
}

4. 反转链表

(1)题目描述

定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。

示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL

(2)题目分析

本题的重点在于设置一个前节点和当前节点,通过不断更新这两个节点,并令当前节点指向前一个节点,最终实现链表的反转。

(3)代码

package swordOffer.day4;

import charpter2.ListNode;

/**
 * @author chengzhengda
 * @version 1.0
 * @date 2020-03-24 19:08
 * @desc
 */
public class t19 {
    public static ListNode reverseList(ListNode head) {
        ListNode past = null;
        ListNode cur = head;
        while (cur != null) {
            ListNode temp = cur.next;
            cur.next = past;
            past = cur;
            cur = temp;
        }
        return past;
    }

    public static void main(String[] args) {
        ListNode listNode1 = new ListNode(1);
        ListNode listNode2 = new ListNode(2);
        ListNode listNode3 = new ListNode(3);
        ListNode listNode4 = new ListNode(4);
        listNode1.next = listNode2;
        listNode2.next = listNode3;
        listNode3.next = listNode4;

        ListNode res = reverseList(listNode1);
        while (res != null) {
            System.out.println(res.val);
            res = res.next;
        }
    }
}

5. 合并两个排序的链表

(1)题目描述

输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。

示例1:
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4

(2)题目分析

本题的重点在于设置一个虚拟节点,通过比较两个链表的节点值大小,最后输出虚拟节点的下一个节点即可。

(3)代码

package swordOffer.day4;

import charpter2.ListNode;

/**
 * @author chengzhengda
 * @version 1.0
 * @date 2020-03-24 19:33
 * @desc
 */
public class t20 {
    public static ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode temp = new ListNode(0);
        ListNode res = temp;
        while (l1 != null && l2 != null) {
            if (l1.val < l2.val) {
                temp.next = l1;
                l1 = l1.next;
            } else {
                temp.next = l2;
                l2 = l2.next;
            }
            temp = temp.next;
        }
        temp.next = l1 != null ? l1 : l2;
        return res.next;
    }

    public static void main(String[] args) {
        ListNode listNode11 = new ListNode(1);
        ListNode listNode12 = new ListNode(3);
        ListNode listNode13 = new ListNode(5);
        ListNode listNode14 = new ListNode(7);
        listNode11.next = listNode12;
        listNode12.next = listNode13;
        listNode13.next = listNode14;

        ListNode listNode21 = new ListNode(2);
        ListNode listNode22 = new ListNode(4);
        ListNode listNode23 = new ListNode(6);
        ListNode listNode24 = new ListNode(8);
        listNode21.next = listNode22;
        listNode22.next = listNode23;
        listNode23.next = listNode24;

        ListNode res = mergeTwoLists(listNode11, listNode21);
        while (res != null) {
            System.out.println(res.val);
            res = res.next;
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值