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;
}
}
}