剑指offer(题记一)

目录

JZ8 二叉树的下一个结点​编辑​编辑

JZ11 旋转数组的最小数字

JZ26 树的子结构

JZ21 调整数组顺序使奇数位于偶数前面(一)

JZ7 重建二叉树

JZ51 数组中的逆序对

JZ8 二叉树的下一个结点

/**
 * struct TreeLinkNode {
 *	int val;
 *	struct TreeLinkNode *left;
 *	struct TreeLinkNode *right;
 *	struct TreeLinkNode *next;
 * };
 */
/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param pNode TreeNode类 
 * @return TreeNode类
 */
struct TreeLinkNode* GetNext(struct TreeLinkNode* pNode ) {
    // write code here
    if(pNode==NULL)
    return NULL;
    if(pNode->right!=NULL)// 如果当前节点有右子树,它的下一个节点为其右子树中最左侧的节点
    {
        pNode=pNode->right;// 如果当前节点的右子树没有左子树,它的下一个结点,就是它的右子树
        while(pNode->left!=NULL)// 如果当前节点的右子树有左子树,它的下一个节点为其右子树中最左侧的节点
        {
            pNode=pNode->left;
        }
        return pNode;
    }
    else//当前节点没有右子树
    {
        //只要pNode不在它的父结点的右孩子中,就输出该父结点
        while(pNode->next)
        {
            //pNode不是根结点
            if(pNode==pNode->next->left)//当前结点是它父亲结点的左孩子
            {
                //根据中序遍历,它的父亲节点就是它的下一个结点
                return pNode->next;
            }
            pNode=pNode->next;//如果当前结点是它父亲结点的右孩子,先找到当前结点的父亲结点,再向上判断该父亲结点是否是其父亲结点的左孩子,直到找到是父亲结点左孩子的结点,再返回这个结点的父亲结点
        }
        return NULL;
    }
}

JZ11 旋转数组的最小数字

/**
 * 
 * @param rotateArray int整型一维数组 
 * @param rotateArrayLen int rotateArray数组长度
 * @return int整型
 */
int minNumberInRotateArray(int* rotateArray, int rotateArrayLen ) {
    // write code here
      int left=0,right=rotateArrayLen-1;
    while(left<=right)
    {
        int mid=left+(right-left)/2;
        if(rotateArray[mid]>rotateArray[right])//中间的数比右边的大,在右边区间进行查找
        {    
            left=mid+1;       
        }
        else if(rotateArray[mid]==rotateArray[right])//中间值等于右边值
        {
            right--;
        }
        else //中间的数比右边的小,在左边区间进行查找
        {
            if(mid==0||rotateArray[mid]<rotateArray[mid-1])// 如果中间值是最小值
            {
                return rotateArray[mid];// 直接返回该值
            }
            else
                right=mid;// 否则最小值在左半边,右侧指针缩小到 [left, mid−1]
            }
        }
    return rotateArray[left];// 如果最小值不在 left 到 right 以内,那么最小值肯定为 第1个元素
}

深度优先遍历算法(dfs)

深度优先遍历算法的核心部分是通过递归的方式依次访问每个邻接节点,由于递归本身就可以压栈和出栈,因此在实现时常常使用栈来记录访问过的节点。为了保证每个节点都只被访问一次,还需要应用一个标记数组来表示每个节点是否已经被访问了。

JZ26 树的子结构

typedef struct TreeNode Node; 

int IsEqual(Node* Root1, Node* Root2)
{
    // 如果pRoot2为空,说明已经匹配完了子树,返回true
	if (Root2 == NULL)
		return 1;
    // 如果pRoot1为空,说明没有匹配到对应的节点,返回false
	if (Root1 == NULL)
		return 0;
    // 如果当前节点的值不相等,返回false
	if (Root1->val != Root2->val)
		return 0;
    // 看当前结点的左右子树是否匹配
	else
		return(IsEqual(Root1->left, Root2->left) && IsEqual(Root1->right, Root2->right));
}
bool HasSubtree(struct TreeNode* pRoot1, struct TreeNode* pRoot2 ) {
    int result = 0;
    //while循环进行搜索。每次循环都需要更新pRoot1的值
	if (pRoot1 && pRoot2)
	{
        // 如果当前节点匹配,进入递归判断子树是否匹配
		if (pRoot1->val == pRoot2->val)
			result = IsEqual(pRoot1, pRoot2);
        // 当前结点不匹配,判断左右子树结点是否匹配
		if (!result)
			result = HasSubtree(pRoot1->left, pRoot2);
        
		if(!result)
			result = HasSubtree(pRoot1->right, pRoot2);
	}
	return result;
}

JZ21 调整数组顺序使奇数位于偶数前面(一)

/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param array int整型一维数组 
 * @param arrayLen int array数组长度
 * @return int整型一维数组
 * @return int* returnSize 返回数组行数
 */
int* reOrderArray(int* array, int arrayLen, int* returnSize ) {
    // write code here
    int*len1=(int*)malloc(sizeof(int) *(arrayLen+1));
    int*len2=(int*)malloc(sizeof(int) *(arrayLen+1));
    memset(len1, 0, sizeof(arrayLen+1));
    memset(len2, 0, sizeof(arrayLen+1));
    int i=0;
    int j=0;
    int k=0;
    for(i=0;i<arrayLen;i++)
    {
        if(array[i]%2==1)
        {
            len1[j++]=array[i];//存放奇数
        }
        else {
            len2[k++]=array[i];//存放偶数
        }
    }
    for (int i = 0; i < k; i++) {
        len1[j+ i] = len2[i];//将len2中的偶数放在len1的后面
    }
    *returnSize=arrayLen;
    free(len2);
    return len1;
}

JZ7 重建二叉树

/**
 * struct TreeNode {
 *  int val;
 *  struct TreeNode *left;
 *  struct TreeNode *right;
 * };
 *
 * C语言声明定义全局变量请加上static,防止重复定义
 */
/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 *
 * @param pre int整型一维数组
 * @param preLen int pre数组长度
 * @param vin int整型一维数组
 * @param vinLen int vin数组长度
 * @return TreeNode类
 */
struct TreeNode* reConstructBinaryTree(int* pre, int preLen, int* vin, int vinLen )
{
    if (preLen == 0||vinLen==0) {
        return NULL;
    }
    // 创建一个新的结点,并将前序遍历序列的第一个元素作为该结点的数据
    struct TreeNode* newnode=(struct TreeNode*)malloc(sizeof(struct TreeNode));
    memset(newnode, 0, sizeof(struct TreeNode));
    newnode->val=* pre;
    int i=0;
    // 在中序遍历序列中查找该结点的位置
    for (i = 0; i < vinLen; i++) {
        if (vin[i] == *pre) {
            break;
        }
    }
    //pre 1~site 和 vin 0-site 的内容
    newnode->left=reConstructBinaryTree(pre+1,i,vin,i);
    //pre (site + 1) ~ 7 和 vin (site + 1) ~ 7 的内容
    newnode->right=reConstructBinaryTree(pre+i+1,preLen-i-1,vin+i+1,vinLen-i-1); 
    return newnode;
}

JZ51 数组中的逆序对

int InversePairs(int* data, int dataLen ) {
    // 假设一串数组 1 2 3 5 2 6 7 8 1,逆序对肯定是比2大的 以及比最后一个1大的,冒泡排序问题
    if(data==NULL||dataLen==0||dataLen==1)
        return 0;
    long int total=0;//计算逆序对个数
    for(int i=dataLen-1;i>=0;i--){
        int k=i-1;
        while(k>=0){
            if(data[i]<data[k])//如果前边的数比后边大
                total++;//逆序对个数加1
            k--;//往前查找看有没有比当前数大的
        }
    }
    return total%1000000007;
}
int reversePairs(int* nums, int numsSize){
if(nums==NULL||numsSize==0||numsSize==1)
{
    return 0;
}
long int total=0;
for(int i=0;i<numsSize;i++)
{
    for(int j=i+1;j<numsSize;j++)
    {
        if(nums[i]>nums[j])
        {
            total++;
        }
    }
}
return total%1000000007;
}

冒泡排序,只是每次交换位置的时候total加1。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值