292. 尼姆游戏(Nim Game)
有一堆石头,两个人轮流从中取出1到3块石头,取得最后一块石头的是胜者。
思路:
若石头总数n是4的倍数,则后手有必胜法:每次取完后,保持剩余石头数是4的倍数。
若n不是4的倍数,则先手就有必胜法了。
return n%4 != 0;
7. 翻转整数
考虑正负数,将整数的各位颠倒。如果颠倒后的结果溢出了,就输出0。
这里为了方便地处理溢出问题,使用一个long变量保存结果。
class Solution {
public:
int reverse(int x) {
long res = 0;
while(x) {
res = res*10 + x%10;
x /= 10;
}
return (res<INT_MIN || res>INT_MAX) ? 0 : res;
}
};
安卓九宫格解锁有多少种可能
思路:
深度优先遍历,期间判断当前位置和上一个位置之间是不是还存在一个数,如果是,该数之前有没有被访问过。如果存在且该数还没有被访问过,就跳过。
代码:
int book[10]={
0};
int num[10]={
0};
int ans=0;
int m[10][10]={
0};
void dfs(int cnt) {
if(cnt>4) ans++;
for(int i = 1; i<=9; i++){
if(book[i]==0){
if(m[i][num[cnt-1]] && book[ m[i][num[cnt-1]] ]==0) //如果当前i和上一个位置之间还存在一个节点,同时该节点没有被访问过
continue;
num[cnt] = i;//该手势的第cnt位是i
book[i] = 1;//标记数字i
dfs(cnt+1);
book[i] = 0;//撤销数字i的标记
}
}
}
int main() {
int n;
//while(cin>>n) {
// ;
//}
m[1][3]=2;
m[4][6]=5;
m[7][9]=8;
m[1][7]=4;
m[2][8]=5;
m[3][9]=6;
m[1][9]=5;
m[3][7]=5;
for(int i = 1; i<=9; i++)
for(int j = i+1; j<=9; j++)
m[j][i] = m[i][j];
dfs(1);
cout<<ans<<endl;
return 0;
}
33. 在翻转的排序数组中查找某个数
假设有一个排序的按未知的旋转轴旋转的数组(比如,0 1 2 4 5 6 7 可能成为4 5 6 7 0 1 2)。给定一个目标值进行搜索,如果在数组中找到目标值返回数组中的索引位置,否则返回-1。
你可以假设数组中不存在重复的元素。
思路:
二分查找,主要是要考虑全面。考虑nums[mid]落在前半段还是后半段。
class Solution {
public:
int search(vector<int>& nums, int target) {
int left=0,right=nums.size()-1;
int mid=0;
while(left<=right)
{
mid=(left+right)/2;
if(nums[mid]==target)
return mid;
//如果mid落在了后半段
if(nums[mid]<nums[left])
{
if(nums[mid]<target && target<=nums[right])
left=mid+1;
else
right=mid-1;
}
//如果mid落在了前半段
else
{
if(nums[mid]>target && target>=nums[left])
right=mid-1;
else
left=mid+1;
}
}
return -1;
}
};
258. 将各位数相加(Add Digits)
将一个整数的各位数相加,再将相加结果的各位数相加……直到相加结果是个位数结束。求该个位数。
例:456->4+5+6=15->1+5=6
思路:
[n*10^(m)]%9 = [n*99...9 + n]%9 = n%9
num%9 = (num各位相加的和)%9 = …… = (所求个位数)%9
设所求个位数为a,则
- 当num%9==0时,a=9;
- 当num%9!=0时,a=num%9
上面的讨论也可以用一句话描述:
return (num-1)%9+1;
319. 翻转灯泡
有n盏灯,初始状态是全灭。第1次,全部打开;第2次,每2盏灯翻转状态;第i次,每i盏灯翻转状态;……;第n次,最后一盏灯翻转状态。求此时亮着的灯的个数。
思路:
第i盏灯如果亮着,说明它有奇数个因子。对i而言,除了1和i本身,若p*q=i,则i有成对的因子,除非p=q,即i是平方数。所以,题目实际上是求n以内平方数的个数。
return (int)Math.sqrt(n);
13. 罗马数字转换成阿拉伯数字
罗马数字有如下符号:
Ⅰ(1)Ⅴ(5)Ⅹ(10)L(50)C(100)D(500)M(1000)
计数规则:
- 若干相同数字连写表示的数是这些罗马数字的和,如III=3;
- 小数字在大数字前面表示的数是用大数字减去小数字,如IV=4;
- 小数字在大数字后面表示的数是用大数字加上小数字,如VI=6;
组合规则:
- 基本数字Ⅰ、X 、C 中的任何一个,自身连用构成数目,或者放在大数的右边连用构成数目,都不能超过三个;放在大数的左边只能用一个。
- 不能把基本数字 V 、L 、D 中的任何一个作为小数放在大数的左边采用相减的方法构成数目;放在大数的右边采用相加的方式构成数目,只能使用一个。
- V 和 X 左边的小数字只能用Ⅰ。
- L 和 C 左边的小数字只能用X。
- D 和 M 左 边的小数字只能用 C 。
思路:
从前往后遍历罗马数字,如果某个数比前一个数小,则把该数加入到结果中;反之,则在结果中两次减去前一个数并加上当前这个数;
class Solution {
public:
int romanToInt(string s) {
int sum=0;
int pre=0;
for(int i=0;i<s.size();i++){
int c;
switch(s[i]){
case 'I':c=1;break;
case 'V':c=5;break;
case 'X':c=10;break;
case 'L':c=50;break;
case 'C':c=100;break;
case 'D':c=500;break;
case 'M':c=1000;break;
}
if(c>pre) sum+=c-2*pre;
else sum+=c;
pre=c;
}
return sum;
}
};
12. 阿拉伯数字转换成罗马数字
思路:
按照个-十-百-千的顺序,依次将相应位上的阿拉伯数字转换成罗马数字。如:
十位上的数字(表示0、10、20、……、90)分别表示为”“,”X”, “XX”,”XXX”,”XL”,”L”,”LX”,”LXX”,”LXXX”,”XC”,添加到最终的罗马数字字符串中去。
class Solution {
public:
string intToRoman(int num) {
string thousand[4] = {
"", "M", "MM","MMM"};
string hundred[11] = {
"", "C","CC","CCC","CD","D","DC","DCC","DCCC","CM"};
string ten[11] = {
"", "X", "XX","XXX","XL","L","LX","LXX","LXXX","XC"};
string one[11] = {
"", "I","II","III","IV","V","VI","VII","VIII","IX"};
string result = "";
string* trans[4] = {
one, ten, hundred, thousand};
int index = 0;
while (num > 0) {
result = trans[index][num % 10] + result;
num = num / 10;
index++;
}
return result;
}
};
20. 合法的括号(Java)
Given a string containing just the characters '(', ')', '{', '}', '[' and ']'
, determine if the input string is valid.
The brackets must close in the correct order, "()"
and "()[]{}"
are all valid but "(]"
and "([)]"
are not.
思路:
利用Stack,思路也比较简单,当遇上(
或者[
或者{
,就将它们压栈;当遇上)
或者]
或者}
,如果栈顶元素是对应的左括号,就将该左括号弹出。最后,如果栈为空,就说明合法,否则不合法。
public class Solution {
public boolean isValid(String s) {
Stack stack = new Stack<>();
for(int i=0;i<s.length();i++) {
char c=s.charAt(i);
if(c=='(' || c=='[' || c=='{') {
stack.push(c);
}
if(c==')') {
if(stack.empty()) return false;
if((char)stack.peek()=='(') stack.pop();