【Notes12】剑指offer_03-10题


3.数组中重复的数字

题目链接:https://leetcode-cn.com/problemset/lcof/
在这里插入图片描述

//java版
class Solution {
    
    
    public int findRepeatNumber(int[] nums) {
    
    
        Set<Integer> set =new HashSet<Integer>(); //实例化哈希表,set里每个元素只能存在一种
        int res = -1; 
        for (int num : nums) //num in nums数组里
            if(!set.add(num))  //add成功返回true,不成功返回false
            {
    
      
                res = num;
                break;
            }   
        return res;
    }
}

在这里插入图片描述

//C++版
class Solution {
    
    
public:
    bool duplicate(int nums[], int n, int* out) {
    
    
        for(int i = 0; i < n; i ++)
        {
    
    
            while(nums[i] != i)
            {
    
    
                if(nums[i] == nums[nums[i]])
                {
    
    
                    out[0] = nums[i];
                    return true;
                }
                else
                    swap(nums[i], nums[nums[i]]);
            }
        }
        return false;
    }
};

4.二维数组中的查找

在这里插入图片描述

//java版
class Solution {
    
    
	public boolean findNumberIn2DArray(int[][] array, int target) {
    
    
		//判断数组空,一维和二维判断
		if((array==null||array.length==0)||(array.length==1&&array[0].length==0))
			return false;
			
		int i = 0, j = array[0].length - 1; //ij对应右上角
		while(i <= array.length - 1 && j >= 0)
		{
    
    
			if(array[i][j] == target) return true; //先判断是否相等,否则ij可能越界
			if(array[i][j] > target) j --;
			else i ++;
		}
		return false;
	}
}
//C++版
class Solution {
    
    
public:
    bool Find(int target, vector<vector<int> > array) {
    
    
        if(array.empty() || array[0].empty()) return false;
        
        int i = 0, j = array[0].size() - 1;
        while(i <= array.size() - 1  && j >= 0)
        {
    
    
            if(array[i][j] == target) return true;
            if(array[i][j] > target) j --;  //不看列
            else i ++;  //不看行
        }        
        return false;
    }
};

5.替换空格

请实现一个函数,把字符串 s 中的每个空格替换成"%20"。示例如下:
输入:s = “We are happy.”,输出:“We%20are%20happy.”

//java版
class Solution {
    
    
	public String replaceSpace(String s) {
    
    
		int n = s.length(); //对象调用方法,数组不用加括号
		char[] array = new char[n * 3];
		int size = 0;
		for(int i = 0; i < n; i ++)
		{
    
    
			char c = s.charAt(i);
			if(c == ' ')
			{
    
    
				array[size ++] = '%';
				array[size ++] = '2';
				array[size ++] = '0';
			}
			else
				array[size ++] = c;  //array里保存了替换好的字符串
			}
		String news = new String(array, 0 , size); //从0开始,长度为size
		return news;
	}
}
//C++版
class Solution {
    
    
public:
	void replaceSpace(char *str,int length) {
    
    
        int count = 0; //count计算空格数目
        
        for(int i = 0; i < length; i ++)
        {
    
    
            if(str[i] == ' ')
                count ++;
        }
        //原本空格是1个字符
        //%20是3个字符多了两个,所以i + count * 2
        for(int i = length - 1; i >= 0; i --) //从高到底遍历不会出现覆盖情况
        {
    
    
            if(str[i] != ' ') //正常赋值
                str[i + count * 2] = str[i];
            if(str[i] == ' ')
            {
    
    
                count --; //每多加一个空格需要--
                str[i + count * 2] = '%';
                str[i + count * 2 + 1] = '2';
                str[i + count * 2 + 2] = '0';
            }
        }        
    }
};

6.从尾到头打印链表

输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。示例如下:
输入:head = [1,3,2],输出:[2,3,1]

//java版
class Solution {
    
    
	public int[] reversePrint(ListNode head) {
    
    
		//压栈
		Stack<ListNode> stk = new Stack<ListNode>();
		ListNode temp = head;
		while(temp != null)//一直指向最后一个结点
		{
    
    
			stk.push(temp);
			temp = temp.next;
		}
		int n = stk.size(); //必须用参数传递,不然会pop掉
		int[] res = new int[n];
		for(int i = 0; i < n; i ++)
			res[i] = stk.pop().val; //val值
		return res;
	}
}
//C++版
class Solution {
    
    
public:
    vector<int> printListFromTailToHead(ListNode* head) {
    
    
        /*
        ListNode* p = head;
        stack<int> stk;
        vector<int> result;
        
        while(p != NULL)
        {
            stk.push(p -> val);
            p = p -> next;
        }
        
        int len = stk.size();
        for(int i = 0; i < len; i ++)
        {
            result.push_back(stk.top());
            stk.pop();
        }
        
        return result;
        */
        ListNode* p = head;
        vector<int> result;
        while(p != NULL)
        {
    
    
            result.push_back(p -> val);
            p = p -> next;
        }
        
        return vector<int>(result.rbegin(), result.rend()); //通常begin,end,加r表示逆序
    }
};

7.重建二叉树

在这里插入图片描述
在这里插入图片描述

//java版
class Solution {
    
    
    //树 递归
	int preindex = 0; //记录下遍历了到哪一个
	int inindex = 0;  //遍历到传入数组长度preorder就结束了
	public TreeNode buildTree(int[] preorder, int[] inorder) {
    
    
		return dfs(preorder, inorder, null);
	}
	private TreeNode dfs(int[] preorder, int[] inorder, TreeNode finish)
	{
    
    
		if(preindex == preorder.length || (finish != null && inorder[inindex] == finish.val))
			return null;
		//遍历过程 
		//前序 跟左右
		TreeNode root = new TreeNode(preorder[preindex ++]);
		//左子树
		root.left = dfs(preorder, inorder, root);
		inindex ++;
		//右子树
		root.right = dfs(preorder, inorder, finish);
		return root;
	}
}
//C++版
class Solution {
    
    
public:
    unordered_map<int,int> pos;
    TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
    
    
        int n = pre.size();
        for(int i = 0; i < n; i ++)
            pos[vin[i]] = i;
        
        return dfs(pre, vin, 0, n - 1, 0, n - 1);
    }
    
    TreeNode* dfs(vector<int> pre,vector<int> vin, int pl, int pr, int vl, int vr)
    {
    
    
        //前序 根左右  pre[pl]
        //中序 左根右
        if(pl > pr) return NULL;
        //找根节点
        TreeNode* root = new TreeNode(pre[pl]);
        //左子树的长度k
        int k = pos[pre[pl]] - vl;
        //vl + k 根节点
        root -> left = dfs(pre, vin, pl + 1, pl + k, vl, vl + k - 1);
        root -> right = dfs(pre, vin,pl + k + 1, pr, vl + k + 1, vr);
        
        return root;
    }
    
};

8.二叉树的下一个节点

在这里插入图片描述

//java版
class Solution {
    
    
	public TreeNode inorderSuccessor(TreeNode p) {
    
    
		//左根右
		//中序遍历特点
		//一个结点 有右子树 返回一定是 右子树 最左边的结点
		if(p.right != null)
		{
    
    
			p = p.right;
			while(p.left != null) p = p.left;
			return p;
		}
		//没有右子树 返回的是 父亲结点
		while(p.father != null)
		{
    
    
			if(p == p.father.left)
				return p.father;
			p = p.father;
		}
		return null;
	}
}
//C++版
class Solution {
    
    
public:
    TreeLinkNode* GetNext(TreeLinkNode* p)
    {
    
    
        //右子树存在 右子树最左边的结点
        if(p -> right)
        {
    
    
            p = p -> right;
            while(p -> left) p = p -> left;
            return p;
        }
        
        //右子树不存在 只有左子树
        while(p -> next)
        {
    
    
            //p不是根节点
            if(p == p -> next -> left)
                return p -> next;
            p = p -> next;
        }        
        return NULL;
    }
};

9.用两个栈实现队列

在这里插入图片描述

//java版
class CQueue {
    
    
	//栈 先进后出
	//队列 先进先出
	Stack<Integer> stk1, stk2;
	int size;
	public CQueue() {
    
    
		stk1 = new Stack<Integer>();
		stk2 = new Stack<Integer>();
		size = 0;
	}

	public void appendTail(int value) {
    
    
		//插入一个元素
		//stk1保存 底部存新插入的 顶部存老的
		while(!stk1.isEmpty())
			stk2.push(stk1.pop());
		stk1.push(value);
		while(!stk2.isEmpty())
			stk1.push(stk2.pop());
		size ++;
	}

	public int deleteHead() {
    
    
		//删除队列首部元素 
		//删除栈顶
		if(size == 0)
			return -1;
		int res = stk1.pop();
		size --;
		return res;
	}
}
//C++版
class Solution
{
    
    
public:
    //先进后出  杯子 栈
    //先进先出  管道 队列        
    void push(int node) {
    
    
        stack1.push(node);
    }
    
    void copy(stack<int> &a, stack<int> &b)
    {
    
    
        while(a.size())
        {
    
    
            b.push(a.top());
            a.pop();
        }
    }
    
    int pop() {
    
    
        //1 ——》 2
        // 2 top  pop
        // 2 ——》 1
        copy(stack1, stack2);
        int res = stack2.top();
        stack2.pop();
        copy(stack2, stack1);        
        return res;
    }

private:
    stack<int> stack1;
    stack<int> stack2;
};

10.斐波那契数列

在这里插入图片描述

//java版
class Solution {
    
    
	public int fib(int n) {
    
    
		if(n == 0) return 0;
		if(n?==?1) return 1;
		int first = 0, second = 1;
		int res = 0;
		for(int i = 2; i <= n; i ++)
		{
    
    
			res = (first + second) % 1000000007;
			first = second % 1000000007;
			second = res % 1000000007;
		}
		return res % 1000000007;
	}
}
//C++版
class Solution {
    
    
public:
    int Fibonacci(int n) {
    
    
        if(n == 0) return 0;
        if(n == 1) return 1;
        int first = 0, second = 1;
        int res = 0;
        for(int i = 2; i <= n; i ++)
        {
    
    
            res = first + second;
            first = second;
            second = res;
        }        
        return res;
    }
};

猜你喜欢

转载自blog.csdn.net/weixin_43435675/article/details/107213677