JZ11:二进制中1的个数
题目描述:输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示
解题思路:每次 n & (n-1) 都会使得二进制数据的最右边的一个1变为0,所以有多少个1就会执行循环多少次
public class Solution {
public int NumberOf1(int n) {
int count=0;
while(n!=0){
count++;
n=n&(n-1);
}
return count;
}
}
JZ12:数值的整数次方
题目描述:给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。保证base和exponent不同时为0
解题思路:调用pow方法,需要特别注意,0的0次方等于1
public class Solution {
public double Power(double base, int exponent) {
if(base==0){
return 0;
}
if(base==0&&exponent==0){
return 1;
}
return Math.pow(base,exponent);
}
}
JZ13:调整整数顺序使奇数位于偶数前面
题目描述:输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变
解题思路:两个循环从前往后去遍历,遇到奇数偶数就交换
public class Solution {
public void reOrderArray(int [] array) {
for(int i=0;i<array.length;i++){
for(int j=0;j<array.length-1-i;j++){
if(array[j]%2==0&&array[j+1]%2==1){
int temp=array[j];
array[j]=array[j+1];
array[j+1]=temp;
}
}
}
}
}
JZ14:链表中倒数第k个节点
解题思路:先统计一下有多少个节点。从前往后遍历到第k个输出就行
public class Solution {
public ListNode FindKthToTail(ListNode head,int k) {
ListNode node=head;
int count=0;
if(head==null){
return head;
}
while(node!=null){
count++;
node=node.next;
}
if(count<k){
return null;
}
ListNode cur=head;
for(int i=0;i<count-k;i++){
cur=cur.next;
}
return cur;
}
}
JZ15:反转链表
题目描述:输入一个链表,反转链表后,输出新链表的表头。
解题思路:从头节点开始,利用改变指向来反转
public class Solution {
public ListNode ReverseList(ListNode head) {
if(head==null){//当前为空的话直接返回空
return null;
}
ListNode pre=null;
ListNode next=null;
while(head!=null){
next=head.next;//保存next(下面会更新next,所以要保存)
head.next=pre;//head.next指向pre
pre=head;
head=next;//进行下一个反转
}
return pre;
}
}
JZ16:合并两个有序链表
解题思路:定义一个新的链表,根据list1位置的值list2位置的值去,让新的链表去把这两个链表的值按顺序大小依次添加,
public class Solution {
public ListNode Merge(ListNode list1,ListNode list2){
if(list1==null){//分析链表为空的情况
return list2;
}
if(list2==null){
return list1;
}
ListNode node=new ListNode(0);
ListNode pr1=list1,pr2=list2;
ListNode result=node;
while(pr1!=null&&pr2!=null){//去判断两个val值得大小决定result接下来往哪儿遍历
if(pr1.val<=pr2.val){
result.next=pr1;
result=pr1;
pr1=pr1.next;
}else{
result.next=pr2;
result=pr2;
pr2=pr2.next;
}
}
if(pr1!=null)//判断最后剩的是pr1还是pr2的
result.next=pr1;
if(pr2!=null)
result.next=pr2;
return node.next;
}
}
JZ17:树的子结构
题目描述:输入两棵二叉树A,B,判断B是不是A的子结构(ps:我们约定空树不是任意一个树的子结构)
解题思路:树的问题一般都是用递归来解决,先找到对应的那个根节点,然后往下递归遍历。
public class Solution {
public boolean HasSubtree(TreeNode root1, TreeNode root2) {
boolean flag= false;
if (root2!=null&&root1!=null) {//树不为空才能比较
if(root1.val == root2.val){//找到了root2对应的根节点
flag= sonTree(root1,root2);//去判断是不是子树
}
//如果找不到,就去root的左边找
if (!flag) {
flag= HasSubtree(root1.left,root2);
}
//如果还找不到,就去root的右边找
if (!flag) {
flag=HasSubtree(root1.right,root2);
}
}
return flag;
}
public boolean sonTree(TreeNode node1, TreeNode node2) {
if (node2 == null) {//Tree2为空了,说明节点都对上了
return true;
}
//Tree2还没有遍历完,Tree1却完了。返回false
if (node1 == null) {//Tree1还没完,Tree1完了,说明没对上
return false;
}
if (node1.val != node2.val) { //某一个点没对上,也说明不是
return false;
}
//如果根节点对应的上,那么就分别去子节点里面匹配
return sonTree(node1.left,node2.left) &&sonTree(node1.right,node2.right);
}
}
JZ18:二叉树的镜像
题目描述:就判断是不是这样就行
解题思路:先前序遍历这棵树的每个结点,如果遍历到的结点有子结点,就交换它的两个子节点,当交换完所有的非叶子结点的左右子结点之后,就得到了树的镜像
public class Solution {
public void Mirror(TreeNode root) {
if(root==null){//空树
return;
}
if(root.right==null&&root.left==null){//说明树只有一个节点
return;
}
TreeNode temp=root.left;//交换它的左右节点
root.left=root.right;
root.right=temp;
if(root.right!=null){//为空时说明找到了递归的出口
Mirror(root.right);
}
if(root.left!=null){
Mirror(root.left);
}
}
}
JZ19:顺时针打印矩阵
题目描述:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 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.
解题思路:先把层数算出来,然后依次从左向右、从右上至右下,从右至左,从左下至左上打印
import java.util.ArrayList;
public class Solution {
public ArrayList<Integer> printMatrix(int [][] arr) {
ArrayList<Integer> result = new ArrayList<Integer> ();
int n = arr.length,m = arr[0].length;
if(m==0||n==0)
return result;
int layers = (Math.min(n,m)-1)/2+1;//这个是圆的层数,不是数组的层数
for(int i=0;i<layers;i++){
for(int k = i;k<m-i;k++) {//左至右
result.add(arr[i][k]);
}
for(int j=i+1;j<n-i;j++){//右上至右下
result.add(arr[j][m-i-1]);
}
for(int k=m-i-2;(k>=i)&&(n-i-1!=i);k--){//右至左
result.add(arr[n-i-1][k]);
}
for(int j=n-i-2;(j>i)&&(m-i-1!=i);j--) {//左下至左上
result.add(arr[j][i]);
}
}
return result;
}
}
JZ20:包含min函数的栈
题目描述:定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。
注意:保证测试中不会当栈为空的时候,对栈调用pop()或者min()或者top()方法。
解题思路:定义两个栈来实现,比如放第一个数字3,stack1正常添加,stack2为空,此时也正常添加,添加第二个数字2,stack1添加,stack2不添加,添加第三个数字1,stack1正常添加,由于(node < stack2.peek()),stack2也添加,最终pop出来的stack2.peek()就是最小的
import java.util.Stack;
public class Solution {
Stack<Integer> stack1 = new Stack<>(); //创建两个栈 Stack1作为主栈
Stack<Integer> stack2 = new Stack<>(); //用辅栈来存放最小数据
public void push(int node) {
stack1.push(node); //主栈存放数据
if (stack2.isEmpty()) { //如果辅栈为空,添加该数据。
stack2.push(node);
}
else if (node < stack2.peek()) {//如果新添数据比辅栈最小值还要小,那么辅栈添加该数据
stack2.push(node);
}
}
public void pop() { //在弹出的时候,如果当前弹出值为最小值,辅栈也进行pop。
if(stack1.peek()==stack2.peek())
stack2.pop();
stack1.pop();
}
public int top() {
return stack1.peek(); //top只是返回栈顶元素,不用进行增删操作。
}
public int min() {
return stack2.peek(); //返回辅栈栈顶元素,栈顶存放的是最小元素。
}
}