1、数值的整数次方
2、调整数组顺序使奇数位于偶数前面
3、链表中倒数第k个结点
4、反转链表
5、合并两个排序的链表
6、树的子结构
7、二叉树的镜像
8、顺时针打印矩阵
9、包含min函数的栈
10、栈的压入、弹出序列
11、从上往下打印二叉树
1、数值的整数次方
(1)问题描述:
给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
(2)解题思路:
法一:直接使用Math.power()
法二:先判断指数的正负性,然后执行乘法
(3)代码实现:
法一:
public static double power(double base,int exponent){
return Math.pow(base,exponent);
}
法二:
public double Power(double base, int exponent) {
if(exponent==0)
return 1;
double result=1.0;
if(exponent>0){
for(int i=1;i<=exponent;i++){
result*=base;
}
}else if(exponent<0){
exponent=-exponent;
for(int i=1;i<=exponent;i++){
result/=base;
}
}
return result;
}
2、调整数组顺序使奇数位于偶数前面
(1)问题描述:
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
(2)解题思路:
法一:两两比较,如果遇到相邻两个数左边的是偶数,右边的是奇数,则互换位置;
法二:新建两个数组,分别存放奇数和偶数,然后在将两个数组中的数据返回,空间换时间。
(3)代码实现:
略3、链表中倒数第k个结点
(1)问题描述:
输入一个链表,输出该链表中倒数第k个结点。
(2)解题思路:
法一:复制两个结点,当第一个结点从头走到第k个结点时,第二个结点从头开始走且第一个结点也继续往前走,直到第一个结点走到链表结尾时,第二个结点刚好走到倒数第k
个结点的位置;
法二:使用栈。
(3)代码实现:
法一:
public static ListNode findKthNode(ListNode head,int k){
if (head == null || k<=0){
return null;
}
ListNode pre = head;
ListNode last = head;
for (int i=1;i<k;i++){
if (pre.next != null){
pre = pre.next;
}else {
return null;
}
}
while (pre.next != null){
pre = pre.next;
last = last.next;
}
return last;
}
法二:
public static ListNode findKthNode(ListNode head,int k){
Stack<ListNode> stack = new Stack<ListNode>();
while (head!=null){
stack.push(head.next);
}
int i = 0;
while (i<k-1){
stack.pop();
}
return stack.pop();
}
4、反转链表
(1)问题描述:
输入一个链表,反转链表后,输出链表的所有元素。
(2)解题思路:
一旦调整了指针的指向,链表就断开了,所以在调整指针指向之前,要把该指针指向的结点先保存下来
(3)代码实现:
public ListNode reverseNode(ListNode head){
ListNode pre=null;
ListNode last=null;
while(head!=null)
{
last=head.next;
head.next=pre;
pre=head;
head=last;
}
return pre;
}
5、合并两个排序的链表
(1)问题描述:
输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
(2)解题思路:
每次找出最小的元素,加入到新的链表的后面
(3)代码实现:
public ListNode Merge(ListNode list1,ListNode list2){
if (list1 ==null){
return list2;
}
if (list2 == null){
return list1;
}
ListNode listNode = null;
if (list1.val > list2.val){
listNode = list2;
listNode.next = Merge(list1,list2.next);
}else {
listNode = list1;
listNode.next = Merge(list1.next,list2);
}
return listNode;
}
6、树的子结构
(1)问题描述:
输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
(2)解题思路:
先在树A种找到和树B的根节点的值一样的结点R;
再判断树A中以R为根节点的子树是否包含和树B一样的结构。
(3)代码实现:
public boolean HasSubtree(TreeNode root1,TreeNode root2) {
if(root1==null||root2==null)
return false;
return IsSubtree(root1,root2)||HasSubtree(root1.left,root2)||HasSubtree(root1.right,root2);
}
public boolean IsSubtree(TreeNode root1,TreeNode root2){
if(root2==null)
return true;
if(root1==null)
return false;
if(root1.val==root2.val)
return IsSubtree(root1.left,root2.left)&&IsSubtree(root1.right,root2.right);
else
return false;
}
7、二叉树的镜像
(1)问题描述:
操作给定的二叉树,将其变换为源二叉树的镜像。
(2)解题思路:
迭代
(3)代码实现:
public void Mirror(TreeNode root) {
TreeNode temp=null;
if(root!=null&&(root.left!=null||root.right!=null)){
temp=root.left;
root.left=root.right;
root.right=temp;
Mirror(root.left);
Mirror(root.right);
}
}
8、顺时针打印矩阵
(1)问题描述:
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
(2)解题思路:
法一:记录四个角的位置
法二:记录两个角的位置即左上角和右下角
(3)代码实现:
法一:
public ArrayList<Integer> printMatrix(int [][] matrix) {
int left=0,right=matrix[0].length-1,top=0,boom= matrix.length-1;//记录四个角的位置
ArrayList<Integer> list = new ArrayList<Integer>();
while((right>left)&&(boom>top)){
for(int i=left;i<=right;i++){//从左到右
list.add(matrix[top][i]);
}
for(int i=top+1;i<=boom;i++){//上到下
list.add(matrix[i][right]);
}
for(int i = right-1;i>=left;i--){//右到左
list.add(matrix[boom][i]);
}
for(int i = boom-1;i>top;i--){//下到上
list.add(matrix[i][left]);
}
left++;
right--;
top++;
boom--;
}
if((boom==top)&&(left<right)){//单独剩下一行的情况
for(int i=left;i<=right;i++){
list.add(matrix[top][i]);
}
}
if((left==right)&&(boom>top)){//单独剩下一列的情况
for(int i =top;i<= boom;i++){
list.add(matrix[i][left]);
}
}
if((boom==top)&&(right==left)){//单独剩下一个元素的情况
list.add(matrix[left][boom]);
}
return list;
}
法二:
public static ArrayList<Integer> printMatrix(int[][] matrix) {
ArrayList<Integer> lst = new ArrayList<Integer>();
int i = 0, j = 0;
int x = matrix.length - 1, y = matrix[0].length - 1;
while (i <= x && j <= y) {
lst = add(lst, matrix, i, j, x, y);
i++;
j++;
--x;
--y;
}
return lst;
}
public static ArrayList<Integer> add(ArrayList<Integer> lst, int[][] matrix, int i, int j, int x, int y) {
int a, b;
for (b = j; b <= y; b++)
lst.add(matrix[i][b]);
for (a = i + 1; a < x; a++)
lst.add(matrix[a][y]);
for (b = y; b >= j && i != x; b--)
lst.add(matrix[x][b]);
for (a = x - 1; a > i && j != y; a--)
lst.add(matrix[a][j]);
return lst;
}
9、包含min函数的栈
(1)问题描述:
定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数。
(2)解题思路:
使用两个栈,data栈存需要存储的元素,min栈存小元素;
push栈的时候,元素存进data栈,如果该元素小于上一个存入的元素,则存入min栈,否则不入min栈;
pop:如果data栈和min栈pop出的元素不等,则再将min栈pop出的元素push进去;该步是为了防止min元素被pop出;
top函数为了将min元素移动到栈顶;
min函数均是得到最小元素,得到pop后在push进去,类似与peek()函数。
(3)代码实现:
public class GetMinStack {
Stack<Integer> stack = new Stack<Integer>();
Stack<Integer> min = new Stack<Integer>();
Integer temp = null;
public void push(int node) {
if (temp != null){
if (node <= temp){
temp = node;
min.push(node);
}
stack.push(node);
}else {
temp = node;
min.push(node);
stack.push(node);
}
}
public void pop() {
int num = stack.pop();
int num1 = min.pop();
if (num != num1){
min.push(num1);
}
}
public int top() {
int num = min.pop();
stack.push(num);
return num;
}
public int min() {
int num = min.pop();
min.push(num);
return num;
}
}
另:
import java.util.Stack;
public class Solution {
Stack stack=new Stack();
public void push(int node) {
stack.push(node);
}
public void pop() {
stack.pop();
}
public int top() {
int top=(int)stack.pop();
return top;
}
public int min() {
Stack stack1=new Stack();
int min=(int)stack.pop();
stack1.push(min);
while(!stack.isEmpty()){
int temp=(int)stack.pop();
if(min>temp){
min=temp;
}
stack1.push(temp);
}
while(!stack1.isEmpty()){
stack.push(stack1.pop());
}
return min;
}
}
10、栈的压入、弹出序列
(1)问题描述:
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)
(2)解题思路:
按顺序入栈 同时按弹出顺序出栈,若栈顶元素等于出栈的顺序元素,则出栈;
执行完后判断栈是否为空。
(3)代码实现:
public class PopOrder {
public static boolean isPopOrder(int[] pushA,int[] popA){
if (pushA.length == 0 || popA.length == 0) return false;
if (pushA.length != popA.length) return false;
Stack<Integer> stack = new Stack<>();
for (int i=0,j=0;i<pushA.length;i++){
stack.push(pushA[i]);
while (j < popA.length && stack.peek()==popA[j]){
stack.pop();
j++;
}
}
return stack.isEmpty();
}
11、从上往下打印二叉树
(1)问题描述:
从上往下打印出二叉树的每个节点,同层节点从左至右打印。
(2)解题思路:
层序遍历
(3)代码实现:
public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) {
ArrayList<Integer> intList=new ArrayList<Integer>();
ArrayList<TreeNode> treeList=new ArrayList<TreeNode>();
if(root==null){
return intList;
}
treeList.add(root);
for(int i=0;i<treeList.size();i++){
TreeNode node= treeList.get(i);
if(node.left!=null){
treeList.add(node.left);
}
if(node.right!=null){
treeList.add(node.right);
}
intList.add(node.val);
}
return intList;
}
用队列实现:
public ArrayList<Integer> printValFromTop2Bott(TreeNode tree){
if (tree == null){
return new ArrayList<Integer>();
}
LinkedList<TreeNode> queue = new LinkedList<TreeNode>();
ArrayList<Integer> list = new ArrayList<Integer>();
queue.offer(tree);
while (!queue.isEmpty()){
TreeNode treeNode = queue.poll();
list.add(treeNode.val);
if (tree.leftTree!= null){
queue.offer(treeNode.leftTree);
}
if (treeNode.rightTree != null){
queue.offer(treeNode.rightTree);
}
}
return list;
}