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;
}
};