文章目录
1、一个递增二维数组找目标值
2、字符串的替换:每个空格替换成“%20”
3、链表反转
4、输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树
5、数组的旋转:输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
6、斐波那契数列的第n项
7、青蛙跳台阶问题
8、输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
9、一个数组,使得所有的奇数位于数组的前半部分,并保证奇数和奇数位置不变,偶数同理
10、输入一个链表,输出该链表中倒数第k个结点
11、输入一个链表,反转链表后,输出新链表的表头
12、两个单调递增的链表,输出两个链表合成后的链表
13、输入两棵二叉树A,B,判断B是不是A的子结构
14、操作给定的二叉树,将其变换为源二叉树的镜像
15、在一个排序的链表中,删除重复结点,重复的不保留
16、输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序
17、二叉树的层序遍历
18、判断该数组是不是某二叉搜索树的后序遍历的结果
19、输入一颗二叉树的根节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径
20、输入一个字符串,按字典序打印出该字符串中字符的所有排列
21、数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字
22、topK问题:输入n个整数,找出其中最小的K个数
23、输入两个链表,找出它们的第一个公共结点。
24、输入一棵二叉树,求该树的深度
25、一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字
26、子串划分,子串逆置(“student. a am I“)
27、请实现一个函数按照之字形打印二叉树
28、给定一棵二叉搜索树,请找出其中的第k小的结点
29、ABC三个线程交替打印ABCABC…
30、字符串解码 Decode String(3[a]2[bc])
31、一个链表,奇数位置是升序,偶数位置是降序,返回一个排好序的链表
32、全排列问题,DFS
33、基于递归与回溯实现。全排列1,2,3
1、一个递增二维数组找目标值
//每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序
public boolean find(int target, int[][] arr) {
if (arr == null || arr.length == 0) {
return false;
}
int i = 0;
int j = arr.length - 1;
while (i < arr.length && j >= 0) {
if (target < arr[i][j]) {
j--;
} else if (target > arr[i][j]) {
i++;
} else {
return true;
}
}
return false;
}
2、字符串的替换:每个空格替换成“%20”
public static String replaceSpace(StringBuffer str) {
int count = 0;
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == ' ') {
count++;
}
}
int news_length = str.length() + 2 * count;
int old_end = str.length() - 1;
int new_end = news_length - 1;
str.setLength(news_length);
while (old_end >= 0 && new_end >= 0) {
if (str.charAt(old_end) == ' ') {
str.setCharAt(new_end--, '0');
str.setCharAt(new_end--, '2');
str.setCharAt(new_end--, '%');
--old_end;
} else {
str.setCharAt(new_end--, str.charAt(old_end));
--old_end;
}
}
return str.toString();
}
3、链表反转
public static class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
//方法一:stack方式
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
Stack<Integer> stack = new Stack<>();
while (listNode != null) {
stack.push(listNode.val);
listNode = listNode.next;
}
ArrayList<Integer> arrayList = new ArrayList<>();
while (!stack.empty()) {
arrayList.add(stack.pop());
}
return arrayList;
}
//方法二,逆置数组
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
ArrayList<Integer> list = new ArrayList<>();
while (listNode != null) {
list.add(listNode.val);
listNode = listNode.next;
}
int i = 0;
int j = list.size() - 1;
while (i < j) {
Integer temp = list.get(i);
list.set(i, list.get(j));
list.set(j, temp);
i++;
j--;
}
return list;
}
//测试
ListNode a1 = new ListNode(1);
ListNode a2 = new ListNode(2);
ListNode a3 = new ListNode(3);
ListNode a4 = new ListNode(4);
ListNode a5 = new ListNode(5);
a1.next = a2;
a2.next = a3;
a3.next = a4;
a4.next = a5;
4、输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}
public TreeNode reConstructBinaryTree(int[] pre, int[] in) {
if (pre.length == 0 || in.length == 0) {
return null;
}
return reConstructBinaryTreeCore(pre, 0, pre.length - 1, in, 0, in.length - 1);
}
public TreeNode reConstructBinaryTreeCore(int[] pre, int preStart, int preEnd, int[] in, int inStart, int inEnd) {
if (preStart > preEnd || inStart > inEnd) {
return null;
}
TreeNode root = new TreeNode(pre[preStart]);
int i = inStart;
for (; i <= inEnd; i++) {
if (in[i] == pre[preStart]) {
root.left = reConstructBinaryTreeCore((pre,preStart+1, i- inStart+preStart, in, inStart, i-1);
root.right = reConstructBinaryTreeCore((pre, i- inStart+preStart+1,preEnd, in, i+1, inEnd);
break;
}
}
return root;
}
5、数组的旋转:输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
//方法一:类似于冒泡排序
public int minNumberInRotateArray(int[] array) {
if (array == null || array.length == 0) {
return 0;
}
for (int i = 0; i < array.length - 1; i++) {
if (array[i] > array[i + 1]) {
return array[i + 1];
}
}
return array[0];
}
//方法二:二分
public int minNumberInRotateArray(int[] array) {
int low = 0;
int high = array.length - 1;
while (low < high) {
int mid = low + (high - low) / 2;
if (array[mid] > array[high]) {
//出现这种情况的array类似[3,4,5,6,0,1,2],此时最小数字一定在mid的右边。
//low = mid + 1
low = mid + 1;
} else if (array[mid] == array[high]) {
//出现这种情况的array类似 [1,0,1,1,1] 或者[1,1,1,0,1],此时最小数字不好判断在mid左边
//还是右边,这时只好一个一个试
high = high - 1;
} else {
//出现这种情况的array类似[2,2,3,4,5,6,6],此时最小数字一定就是array[mid]或者在mid的左
//边。因为右边必然都是递增的。
//high = mid
high = mid;
}
}
return array[low];
}
6、斐波那契数列的第n项
public int Fibonacci(int n) {
if (n == 0) {
return 0;
}
int first = 1;
int second = 1;
int third = 1;
while (n > 2) {
third = first + second;
first = second;
second = third;
--n;
}
return third;
}
7、青蛙跳台阶问题
//方法一:动规实现
public int JumpFloor(int target) {
int[] dp = new int[target + 1];
dp[0] = 1;
dp[1] = 1;
for (int i = 2; i <= target; i++) {
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[target];
}
//方法二:
public int JumpFloor(int target) {
int first = 1;
int second = 2;
int third = target;
while (target > 2) {
third = first + second;
first = second;
second = third;
--target;
}
return third;
}
8、输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
public int NumberOf1(int n) {
int count = 0;
while (n != 0) {
n &= (n - 1);
count++;
}
return count;
}
9、一个数组,使得所有的奇数位于数组的前半部分,并保证奇数和奇数位置不变,偶数同理
//插入排序的思想
public void reOrderArray(int[] array) {
int k = 0;
for (int i = 0; i < array.length; i++) {
if ((array[i] >> 1) == 1) {
int temp = array[i];
int j = i;
while (j > k) {
array[j] = array[j - 1];
j--;
}
array[k++] = temp;
}
}
}
10、输入一个链表,输出该链表中倒数第k个结点
public ListNode FindKthToTail(ListNode head, int k) {
ListNode head1 = head;
while (k > 0) {
head1 = head1.next;
k--;
}
while (head1.next != null) {
head = head.next;
head1 = head1.next;
}
return head;
}
11、输入一个链表,反转链表后,输出新链表的表头
//方法一:三指针
public ListNode ReverseList(ListNode head) {
if (head == null || head.next == null) {
return head;
}
//4-5-6
ListNode first = head;
ListNode sencond = head.next;
ListNode third = sencond.next;
while (third != null) {
sencond.next = first;
first = sencond;
sencond = third;
third = third.next;
}
sencond.next = first;//当上面翻转完毕或者只有两个节点的时候,处理一下,翻转一下
head.next = null;//设置一下第一个节点的指向null
head = sencond;//头节点指向最后一个节点
return head;
}
//方法二:头插法
public ListNode ReverseList1(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode new_head = null;
while (head != null) {
ListNode pre = head;
head = head.next;
pre.next = new_head;
new_head = pre;
}
return head;
}
12、两个单调递增的链表,输出两个链表合成后的链表
public ListNode Merge(ListNode list1, ListNode list2) {
if (list1 == null) {
return list2;
}
if (list2 == null) {
return list1;
}
if (list1.val > list2.val) {
list1.next = Merge(list1.next, list2);
return list1;
} else {
list2.next = Merge(list1, list2.next);
return list2;
}
}
13、输入两棵二叉树A,B,判断B是不是A的子结构
public boolean IsSameFromBegin(TreeNode begin, TreeNode beginSub) {
if (begin == null || beginSub == null) {
return false;
}
if (HasSubtree(begin, beginSub)) {
return true;
}
return IsSameFromBegin(begin.left, beginSub) || IsSameFromBegin(begin.right, beginSub);
}
public boolean HasSubtree(TreeNode root1, TreeNode root2) {
if (root2 == null) {
return true;
}
if (root1 == null) {
return false;
}
if (root1.val != root2.val) {
return false;
}
return HasSubtree(root1.left, root2.left) && HasSubtree(root1.right, root2.right);
}
14、操作给定的二叉树,将其变换为源二叉树的镜像。
public void Mirror(TreeNode root) {
if (root == null) {
return;
}
TreeNode temp = root.left;
root.left = root.right;
root.right = temp;
Mirror(root.left);
Mirror(root.right);
}
15、在一个排序的链表中,删除重复结点,重复的不保留
public ListNode deleteDuplication(ListNode pHead) {
if (pHead == null) {
return null;
}
ListNode newNode = new ListNode(-1);
pHead.next = newNode;
ListNode pre = newNode;
ListNode last = pHead;
while (last != null) {
//不重复的时候直接往下走
while (last.next != null && last.val != last.next.val) {
last = last.next;
pre = pre.next;
}
//重复的情况
while (last.next != null && last.val == last.next.val) {
last = last.next;
}
if (pre.next != last) {
pre.next = last.next;
}
last = last.next;
}
return newNode.next;
}
16、输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。
public boolean IsPopOrder(int[] pushA, int[] popA) {
if (pushA == null || pushA.length == 0 || popA == null || popA.length == 0) {
return false;
}
Stack<Integer> stack = new Stack<>();
int popAi = 0;
int pushAi = 0;
stack.push(pushA[pushAi]);
while (popAi < popA.length && pushAi < pushA.length) {
if (!stack.isEmpty() && stack.peek() == popA[popAi]) {
popAi++;
stack.pop();
} else if (pushAi < pushA.length) {
stack.push(pushAi);
} else {
break;
}
}
if (stack.empty()) {
return true;
} else {
return false;
}
}
17、二叉树的层序遍历
public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) {
if (root == null) {
return new ArrayList<>();
}
Queue<TreeNode> queue = new LinkedList<>();
ArrayList<Integer> result = new ArrayList<>();
queue.offer(root);
while (!queue.isEmpty()) {
TreeNode father = queue.poll();
result.add(father.val);
if (father.left != null) {
queue.offer(father.left);
}
if (father.right != null) {
queue.offer(father.right);
}
}
return result;
}
18、判断该数组是不是某二叉搜索树的后序遍历的结果
public boolean VerifySquenceOfBST(int[] sequence) {
if (sequence.length == 0) {
return false;
}
return VerifySquenceOfBSTCore(sequence, 0, sequence.length - 1);
}
public boolean VerifySquenceOfBSTCore(int[] sequence, int start, int end) {
if (start >= end) {
return true;
}
int root = sequence[end];
int i = 0;
while (i < end && sequence[i] > root) {
i++;
}
for (int j = i; j < end; j++) {
if (sequence[j] < root) {
return false;
}
}
return VerifySquenceOfBSTCore(sequence, 0, i - 1) && VerifySquenceOfBSTCore(sequence, i, end - 1);
}
19、输入一颗二叉树的根节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径
//DFS回溯
public ArrayList<ArrayList<Integer>> FindPath(TreeNode root, int target) {
ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
ArrayList<Integer> list = new ArrayList<>();
FindPathDFS(root, target, result, list);
return result;
}
public void FindPathDFS(TreeNode root, int target, ArrayList<ArrayList<Integer>>
result, ArrayList<Integer> list) {
if (root == null) {
return;
}
list.add(root.val);
target -= root.val;
if (root.left == null && root.right == null && target == 0) {
result.add(new ArrayList<Integer>(list));
}
FindPathDFS(root.left, target, result, list);
FindPathDFS(root.right, target, result, list);
list.remove(list.size() - 1);
}
20、输入一个字符串,按字典序打印出该字符串中字符的所有排列
//全排列问题,DFS
public ArrayList<String> Permutation(String str) {
ArrayList<String> result = new ArrayList<>();
if (str != null && str.length() > 0) {
PermutationHelper(str.toCharArray(), 0, result);
Collections.sort(result);
}
return result;
}
public void PermutationHelper(char[] str, int start, ArrayList<String> result) {
if (start == str.length - 1) {
if (!IsExist(result, str)) {
result.add(new String(str));
}
return;
}
for (int i = start; i < str.length; i++) {
Swap(str, start, i);
PermutationHelper(str, start + 1, result);
Swap(str, start, i);
}
}
public void Swap(char[] str, int i, int j) {
char temp = str[i];
str[i] = str[j];
str[j] = temp;
}
public boolean IsExist(ArrayList<String> result, char[] str) {
return result.contains(String.valueOf(str));
}
21、数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字
//定义map,使用<数字,次数>的映射关系,最后统计每个字符出现的次数
public int MoreThanHalfNum_Solution(int[] array) {
if (array == null) {
return 0;
}
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < array.length; i++) {
if (map.containsKey(array[i])) {
int count = map.get(array[i]);
count++;
map.put(array[i], count);
} else {
map.put(array[i], 1);
}
if (map.get(array[i]) > array.length / 2) {
return array[i];
}
}
return 0;
}
//排序,出现次数最多的数字,一定在中间位置。然后检测中间出现的数字出现的次数是否符合要求
public int MoreThanHalfNum_Solution(int[] array) {
if (array == null) {
return 0;
}
Arrays.sort(array);
int target = array[array.length / 2];
int count = 0;
for (int i = 0; i < array.length; i++) {
if (target == array[i]) {
count++;
}
}
if (count > array.length / 2) {
return target;
}
return 0;
}
//目标条件:目标数据超过数组长度的一半,那么对数组,我们同时去掉两个不同的数字,
//到最后剩 下的一个数就是该数字。如果剩下两个,那么这两个也是一样的,就是结果),
//在其基础上把最后剩下的一个 数字或者两个回到原来数组中,
//将数组遍历一遍统计一下数字出现次数进行最终判断。
public int MoreThanHalfNum_Solution(int[] array) {
if (array == null) {
return 0;
}
int target = array[0];
int times = 1;
for (int i = 1; i < array.length; i++) {
if (times == 0) {
target = array[i];
times = 1;
} else if (array[i] == target) {
times++;
} else {
times--;
}
}
times = 0;
for (int i = 0; i < array.length; i++) {
if (target == array[i]) {
times++;
}
}
return times > array.length / 2 ? target : 0;
}
22、topK问题:输入n个整数,找出其中最小的K个数
public ArrayList<Integer> GetLeastNumbers_Solution(int[] input, int k) {
ArrayList<Integer> list = new ArrayList<>();
if (input == null || k <= 0 || k > input.length) {
return list;
}
PriorityQueue<Integer> queue = new PriorityQueue<>(k, Collections.reverseOrder());
for (int i = 0; i < input.length; i++) {
if (i < k) {
queue.offer(input[i]);
} else {
if (input[i] < queue.peek()) {
queue.poll();
queue.offer(input[i]);
}
}
}
for (int i = 0; i < k; i++) {
list.add(queue.poll());
}
return list;
}
23、输入两个链表,找出它们的第一个公共结点。
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
if (pHead1 == null || pHead2 == null) {
return null;
}
int length1 = GetListLength(pHead1);
int length2 = GetListLength(pHead2);
int step = Math.abs(length1 - length2);
if (length1 > length2) {
while (step > 0) {
pHead1 = pHead1.next;
step--;
}
} else {
while (step > 0) {
pHead2 = pHead2.next;
step--;
}
}
while (pHead1 != null && pHead2 != null) {
if (pHead1 == pHead2) {
return pHead1;
}
pHead1 = pHead1.next;
pHead2 = pHead2.next;
}
return null;
}
public int GetListLength(ListNode list) {
if (list == null) {
return 0;
}
int len = 0;
while (list != null) {
len++;
list = list.next;
}
return len;
}
24、输入一棵二叉树,求该树的深度
//方法一:递归
public int TreeDepth(TreeNode root) {
if (root == null) {
return 0;
}
return Math.max(TreeDepth(root.left), TreeDepth(root.right)) + 1;
}
//方法二:层序遍历
public int TreeDepth(TreeNode root) {
if (root == null) {
return 0;
}
Queue<TreeNode> q = new LinkedList<>();
q.offer(root);
int depth = 0;
while (!q.isEmpty()) {
int size = q.size();
depth++;
for (int i = 0; i < size; i++) {
TreeNode curr = q.poll();
if (curr.left != null) q.offer(curr.left);
if (curr.right != null) q.offer(curr.right);
}
}
return depth;
}
25、一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字
public void FindNumsAppearOnce(int[] array, int num1[], int num2[]) {
if (array == null || num1 == null || num2 == null) {
return;
}
num1[0] = 0;
num2[0] = 0;
int result = array[0];
for (int i = 1; i < array.length; i++) {
result ^= array[i];
}
int length = Integer.SIZE;
int flag = 1;
while (length >= 0) {
length -= 1;
if (((flag << length) & result) != 0) {
flag <<= length;
break;
}
}
for (int i = 0; i < array.length; i++) {
if ((array[i] & flag) == 0) {
num1[0] ^= array[i];
} else {
num2[0] ^= array[i];
}
}
}
26、子串划分,子串逆置(“student. a am I“)
public String ReverseSentence(String str) {
if (str == null || str.length() == 0) {
return str;
}
char[] list = str.toCharArray();
int len = list.length;
int i = 0;
int j = i;
while (i < len) {
while (i < len && !Character.isSpace(list[i])) i++;
Reverse(list, j, i - 1);
while (i < len && Character.isSpace(list[i])) i++;
j = i;
}
Reverse(list, j, i - 1);
Reverse(list, 0, i - 1);
return new String(list);
}
27、请实现一个函数按照之字形打印二叉树
public ArrayList<ArrayList<Integer>> Print(TreeNode pRoot) {
ArrayList<ArrayList<Integer>> result = new ArrayList<>();
if (pRoot == null) {
return result;
}
Stack<TreeNode> st = new Stack<>();
Queue<TreeNode> q = new LinkedList<>();
st.push(pRoot);
int dir = 1;
ArrayList<Integer> list = new ArrayList<>();
while (!st.empty()) {
int size = st.size();
for (int i = 0; i < size; i++) {
TreeNode curr = st.pop();
list.add(curr.val);
TreeNode first = (dir == 1) ? curr.left : curr.right;
TreeNode second = (dir == 1) ? curr.right : curr.left;
if (first != null) q.offer(first);
if (second != null) q.offer(second);
}
result.add(new ArrayList(list));
list.clear();
while (!q.isEmpty()) {
st.push(q.poll());
}
dir = (dir == 1) ? 2 : 1;
}
return result;
}
28、给定一棵二叉搜索树,请找出其中的第k小的结点
TreeNode KthNode(TreeNode pRoot, int k) {
if (pRoot == null || k <= 0) {
return null;
}
Stack<TreeNode> st = new Stack<>();
TreeNode node = pRoot;
do {
while (node != null) {
st.push(node);
node = node.left;
}
if (!st.empty()) {
node = st.pop();
if (k == 0) {
return node;
}
node = node.right;
}
} while (node != null || !st.empty());
return null;
}
29、ABC三个线程交替打印ABCABC...
public class Main extends Thread {
private volatile static int state = 0;
private static final String name = "ABC";
private int type;
Main(int type) {
this.type = type;
}
@Override
public void run() {
for (int i = 0; i < 10; ) {//类似自旋锁,不成功就一直重试
if (state % 3 == type) {
System.out.println("线程" + type + ":" + name.charAt(type));//type的作用就体现了出来,这里作下标
state++;
i++;//成功输出,才可以自增
}
}
}
public static void main(String[] args) {
new Main(0).start();//0既可以区分线程,又可以代表我要输出ABC的字符下标是几
new Main(1).start();
new Main(2).start();
}
}
30、字符串解码 Decode String(3[a]2[bc])
public static String decodeString(String s) {
int number = 0;
Stack<Integer> n_Stack = new Stack<>();
Stack<StringBuffer> w_Stack = new Stack<>();
StringBuffer val = new StringBuffer();
for(Character c : s.toCharArray()) {//遍历每一个字符
if(Character.isDigit(c)) {//判断是否是整形
number = number*10+c-'0';
}else if(Character.isLetter(c)) {
val.append(c);
}else if(c == '[') {
n_Stack.push(number);
number = 0;
w_Stack.push(val);
val = new StringBuffer();
}else {//这种情况"]"的情况
StringBuffer ss = new StringBuffer();
ss.append(w_Stack.pop());
int n = n_Stack.pop();
for(int i=0;i<n;i++) {
ss.append(val);
}
val = ss;
}
}
return val.toString();
}
31、一个链表,奇数位置是升序,偶数位置是降序,返回一个排好序的链表
public static void main(String[] args) {
Main main = new Main();
ListNode head = main.initList();
main.printList(head);
ListNode[] heads = main.splitList(head);
main.printList(heads[0]);
main.printList(heads[1]);
ListNode reverseHead = main.reverseList(heads[1]);
main.printList(reverseHead);
ListNode mergeHead = main.mergeLists(heads[0], reverseHead);
main.printList(mergeHead);
}
//按照奇偶位拆分成两个链表
private ListNode[] splitList(ListNode head) {
ListNode head1 = null;
ListNode head2 = null;
ListNode cur1 = null;
ListNode cur2 = null;
int count = 1;
while (head != null) {
if (count % 2 == 1) {
if (cur1 != null) {
cur1.next = head;
cur1 = cur1.next;
} else {
cur1 = head;
head1 = cur1;
}
} else {
if (cur2 != null) {
cur2.next = head;
cur2 = cur2.next;
} else {
cur2 = head;
head2 = cur2;
}
}
head = head.next;
++count;
}
//跳出循环,要让最后两个末尾元素的下一个都指向null
cur1.next = null;
cur2.next = null;
ListNode[] heads = new ListNode[]{head1, head2};
return heads;
}
//反转链表
private ListNode reverseList(ListNode head) {
ListNode cur = head;
ListNode pre = null;
ListNode next = null;
while (cur != null) {
next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
return pre;
}
//合并两个有序链表
private ListNode mergeLists(ListNode head1, ListNode head2) {
if (head1 == null && head2 == null) {
return null;
}
if (head1 == null || head2 == null) {
return head1 == null ? head2 : head1;
}
ListNode first = new ListNode(-1);
ListNode cur = first;
while (head1 != null && head2 != null) {
if (head1.val < head2.val) {
cur.next = head1;
head1 = head1.next;
} else {
cur.next = head2;
head2 = head2.next;
}
cur = cur.next;
}
cur.next = head1 != null ? head1 : head2;
return first.next;
}
//初始化链表
private ListNode initList() {
ListNode node1 = new ListNode(1);
ListNode node2 = new ListNode(8);
ListNode node3 = new ListNode(3);
ListNode node4 = new ListNode(6);
ListNode node5 = new ListNode(5);
ListNode node6 = new ListNode(4);
ListNode node7 = new ListNode(7);
ListNode node8 = new ListNode(2);
ListNode node9 = new ListNode(9);
node1.next = node2;
node2.next = node3;
node3.next = node4;
node4.next = node5;
node5.next = node6;
node6.next = node7;
node7.next = node8;
node8.next = node9;
return node1;
}
//打印链表
private void printList(ListNode head) {
if (head == null) {
return;
}
ListNode cur = head;
while (cur.next != null) {
System.out.print(cur.val + "\t");
cur = cur.next;
}
System.out.println(cur.val);
}
32、全排列问题,DFS
//输入字符串abc,则打印出由字符a,b,c
//所能排列出来的所有字符串 abc,acb,bac,bca,cab 和 cba 。
public ArrayList<String> Permutation(String str) {
ArrayList<String> result = new ArrayList<>();
if (str != null && str.length() > 0) {
PermutationHelper(str.toCharArray(), 0, result);
Collections.sort(result);
}
return result;
}
public void PermutationHelper(char[] str, int start, ArrayList<String> result) {
if (start == str.length - 1) {
if (!IsExist(result, str)) {
result.add(new String(str));
}
return;
}
for (int i = start; i < str.length; i++) {
Swap(str, start, i);
PermutationHelper(str, start + 1, result);
Swap(str, start, i);
}
}
public void Swap(char[] str, int i, int j) {
char temp = str[i];
str[i] = str[j];
str[j] = temp;
}
public boolean IsExist(ArrayList<String> result, char[] str) {
return result.contains(String.valueOf(str));
}
33、基于递归与回溯实现。全排列1,2,3
//基于递归与回溯实现。全排列1,2,3的
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
List<Integer> temp = new ArrayList<>();
for (int i : nums) {
temp.add(i);
}
int len = nums.length;
dfs(len, result, temp, 0);
return result;
}
private void dfs(int len, List<List<Integer>> result, List<Integer> temp, int first) {
if (first == len) {
result.add(new ArrayList<>(temp));
}
for (int i = first; i < len; i++) {
Collections.swap(temp,first,i);
dfs(len,result,temp,first+1);
Collections.swap(temp,first,i);
}
}