在一个长度为n+1的数组里的所有数字都在1 ~n的范围内,所以数组中至少有一个数字是重复 的。从数组中找出任意一个重复的数字,但不能 修改输入的数组。如{2,3,5,4,3,2,6,7}得到2或者3

#include <iostream>
#include <vector>
using namespace std;

int duplicateInArray0(vector<int>& nums) {
//暴力 n*n
int n = nums.size();
for (int i = 0; i < n - 1; i++)
{
for (int j = i + 1; j < n; j++)
{
if (nums[i] ^ nums[j] == 0)
return nums[i];
}
}

return 0;
}

int duplicateInArray(vector<int>& nums) {
//二分 n* logn
int l = 1, r = nums.size() - 1;
while (l < r)
{
int mid = l + r >> 1; //[l, mid] [mid+ 1, r]
int count = 0;
for (int i = 0; i < nums.size(); i++)
{
if (nums[i] >= l && nums[i] <= mid)
count++;
}
if (count > mid - l + 1) r = mid;
else l = mid + 1;
}
return l;
}

int main()
{
int a[8] = { 2, 3, 5, 4, 3, 2, 6, 7 };
vector<int> nums;
//将a的所有元素插入到b中
nums.insert(nums.begin(), a, a + 9);
cout << "暴力解答:" << duplicateInArray(nums) << endl;
cout << "二分解答:" << duplicateInArray(nums) << endl;
return 0;

}

  找出数组中重复的数字:

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

void swap( int i, int j) {

}
};

  在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一 列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判 断数组中是否含有该整数。

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

  请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字 符串为We Are Happy.则经过替换之后的字符串为We%20Are% 20Happy。

void replaceSpace(char* str, int length)
{
int count = 0;

for (int i = 0; i < length; i++)
{
if (str[i] == ' ')
count++;
}

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

  输入一个链表,按链表从尾到头的顺序返回一个ArrayList

struct ListNode
{
int val;
struct ListNode* next;
ListNode(int x) :
val(x), next(NULL) {
}
};
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());
}

//输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍

//历的结果中都不含重复的数字。例如输入前序遍历序列{ 1,2,4,7,3,5,6,8 }和中序遍历序列
//{ 4,7,2,1,5,3,8,6 },则重建二叉树并返回

struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x) :val(x), left(NULL), right(NULL) {

}
};

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

  给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点 不仅包含左右子结点,同时包含指向父结点的指针。

struct TreeLinkNode
{
int val;
struct TreeLinkNode* left;
struct TreeLinkNode* right;
struct TreeLinkNode* next;
TreeLinkNode(int x) :val(x), left(NULL), right(NULL), next(NULL) {

}
};

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

  用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型

//先进后出    栈
//先进先出 队列
stack<int> stack1, stack2;
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() {
copy(stack1, stack2);
int res = stack2.top();
stack2.pop();
copy(stack2, stack1);
return res;
}

  要求输入一个整数n,请你输出斐波那契数列的第n项(从0开 始,第0项为0)

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

  旋转数组的最小数字:

int minNumberInRotateArray(vector<int> nums) {
int n = nums.size() - 1;
if (n < 0) return 0;

while (nums[n] == nums[0] && n > 0) n--;
if (nums[n] >= nums[0]) return nums[0];

int l = 0, r = n;
while (l < r)
{
int mid = l + r >> 1; //[l, mid] [mid+1, r]
if (nums[mid] < nums[0]) r = mid;
else l = mid + 1;
}
return nums[r];
}

  矩阵中的路径

C++ 算法(一)_数组

 

 

bool hashPath(char* matrix, int rows, int cols, char* str)
{
if (rows == 1 && cols == 1)
{
if (matrix[0] == str[0])
return true;
else
return false;

//matrix 一维
//str 目标字符串 str \0
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
if (dfs(matrix, rows, cols, str, 0, i, j)) return true;
}
}
return false;
}
}

bool dfs(char* matrix, int rows, int cols, char* str, int u, int x, int y)
{
if (str[u] == '\0') return true;
int dx[4] = { -1, 0, 1,0 }, dy[4] = { 0, 1, 0, -1 };
for (int i = 0; i < 4; i++)
{
int a = x + dx[i], b = y + dy[i];
if (a >= 0 && a < rows && b >= 0 && b < cols && matrix[a * cols + b] == str[u])
{
char t = matrix[a * cols + b];
matrix[a * cols + b] = '*';
if (dfs(matrix, rows, cols, str, u + 1, a, b))
return true;
matrix[a * cols + b] = t;
}
}
return false;
}